Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

extern "C"

1 view
Skip to first unread message

Karel Van Laer

unread,
Sep 4, 2008, 9:55:24 AM9/4/08
to
Hi everyone,

I need to be able to mix C and C++.
The main program is written in C and needs to access C++ code.
To be more specific it's a user defined function in fluent, but this
should not be relevant.

I've allready read that i need to use the extern "C" construction but i
don't seem to be doing it right.

So far i've got this compiled:

<file: cpplib.cpp>
extern "C" int function(); //declaration
int function(){...} //definition
</file: cpplib.cpp>

<file: cpplib.h>
int function(){}
</file: cpplib.h>

<file: cprogram>
#include "cpplib.h"
...//call "function()" somewhere
</file: cprogram>

When i try to run it this generates the following error:
/opt/Fluent.Inc/fluent6.3.26/lnx86/2d/fluent.6.3.26: symbol lookup
error: libudf/lnx86/2d/libudf.so: undefined symbol: init
"init" is the function i'm trying to call here.

I'm hoping somebody here can give me an idea of what i'm doing wrong here.

Karel


Victor Bazarov

unread,
Sep 4, 2008, 10:24:48 AM9/4/08
to
Karel Van Laer wrote:
> I need to be able to mix C and C++.
> The main program is written in C and needs to access C++ code.
> To be more specific it's a user defined function in fluent, but this
> should not be relevant.
>
> I've allready read that i need to use the extern "C" construction but i
> don't seem to be doing it right.
>
> So far i've got this compiled:
>
> <file: cpplib.cpp>
> extern "C" int function(); //declaration
^^^^^^^^^^^^^^^^^^^^^^^^^
Drop that. Instead do

#include "cpplib.h"

> int function(){...} //definition
> </file: cpplib.cpp>
>
> <file: cpplib.h>
> int function(){}

That's simply wrong. You shouldn't *define* functions in headers like
that. Think about it: the empty body? What you should have do is:

#ifdef __cplusplus
extern "C"
#endif
int function();

> </file: cpplib.h>
>
> <file: cprogram>
> #include "cpplib.h"
> ...//call "function()" somewhere
> </file: cprogram>
>
> When i try to run it this generates the following error:
> /opt/Fluent.Inc/fluent6.3.26/lnx86/2d/fluent.6.3.26: symbol lookup
> error: libudf/lnx86/2d/libudf.so: undefined symbol: init
> "init" is the function i'm trying to call here.

'init'? How does the 'init' play into all that? Isn't your function
called 'function'?

>
> I'm hoping somebody here can give me an idea of what i'm doing wrong here.

For one, you're not posting your real code.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Karel Van Laer

unread,
Sep 4, 2008, 10:53:20 AM9/4/08
to
You are right about the readability of my code.
So i'll respond with a cleaner version

<file: cpplib.h>


#ifdef __cplusplus
extern "C" {
#endif

int init(); //declaration
#ifdef __cplusplus
}
#endif
</file: cpplib.h>

<file: cpplib.cpp>
#include "cpplib.h"
int init(){...} //definition
</file: cpplib.cpp>

<file: cprogram>
#include "cpplib.h"
...//call "init()" somewhere
</file: cprogram>

the result remains the same:


/opt/Fluent.Inc/fluent6.3.26/lnx86/2d/fluent.6.3.26: symbol lookup
error: libudf/lnx86/2d/libudf.so: undefined symbol: init

Karel

Uwe Schmitt

unread,
Sep 4, 2008, 11:15:28 AM9/4/08
to
On 4 Sep., 16:53, Karel Van Laer <kvl...@biomath.ugent.be> wrote:
> You are right about the readability of my code.
> So i'll respond with a cleaner version
>
> <file: cpplib.h>
>       #ifdef __cplusplus
>       extern "C" {
>       #endif
>       int init(); //declaration
>       #ifdef __cplusplus
>       }
>       #endif
> </file: cpplib.h>
>
> <file: cpplib.cpp>
>      #include "cpplib.h"
>      int init(){...} //definition
> </file: cpplib.cpp>
>
> <file: cprogram>
>      #include "cpplib.h"
>      ...//call "init()" somewhere
> </file: cprogram>
>
> the result remains the same:
> /opt/Fluent.Inc/fluent6.3.26/lnx86/2d/fluent.6.3.26: symbol lookup
> error: libudf/lnx86/2d/libudf.so: undefined symbol: init
>

Which compilers do you use and how do you use them ?

If you use the gnu compiliers, you should use

g++ -c cpplib.cpp

and then

gcc cprogram.c cpplib.o

Greetings, Uwe

Ian Collins

unread,
Sep 4, 2008, 3:10:02 PM9/4/08
to
Uwe Schmitt wrote:
>
> Which compilers do you use and how do you use them ?
>
> If you use the gnu compiliers, you should use
>
> g++ -c cpplib.cpp
>
> and then
>
> gcc cprogram.c cpplib.o
>
> Greetings, Uwe

That's very unlikely to work. The main program must be compiled and
linked as C++.

--
Ian Collins.

Victor Bazarov

unread,
Sep 4, 2008, 3:46:50 PM9/4/08
to

So, more likely it should be

g++ -c cpplib.cpp
gcc -c cprogram.c
g++ cprogram.o cpplib.o -o cprogram

northern_RATT

unread,
Sep 4, 2008, 10:52:26 PM9/4/08
to
<snip>

> I need to be able to mix C and C++.
> The main program is written in C and needs to access C++ code.
> To be more specific it's a user defined function in fluent, but this
> should not be relevant.
>
> I've allready read that i need to use the extern "C" construction but i
> don't seem to be doing it right.
</snip>

OK. Pardon a rank amature who only lurks here, BUT....
This looks like backwards logic to me. I thought that
'extern C' is a way for C++ code to call undecorated C code(?)
Not the otherway around!
Not that I have ever needed to face this, but I thought that C calling
C++ code needs some type of wrapper?

Confused?
Drew


Alexander Dong Back Kim

unread,
Sep 4, 2008, 11:22:55 PM9/4/08
to

These kinds of problems are really annoying sometimes however
unfortunately using both C and C++ are very common in real world (at
least my world =P). I'm certainly wondering what would be the "best"
practice for avoiding or even relaxing this kinds of issues.

cheers,
Alex Kim

Michael DOUBEZ

unread,
Sep 5, 2008, 3:18:55 AM9/5/08
to
Alexander Dong Back Kim a écrit :

> On Sep 5, 12:52 pm, "northern_RATT" <n...@none.net> wrote:
>> <snip>> I need to be able to mix C and C++.
> These kinds of problems are really annoying sometimes however
> unfortunately using both C and C++ are very common in real world (at
> least my world =P). I'm certainly wondering what would be the "best"
> practice for avoiding or even relaxing this kinds of issues.

Compile your C code with a c++ compiler :)
Most c++ compiler support C99 unless you disable it in the command line.

--
Michael

James Kanze

unread,
Sep 5, 2008, 5:56:43 AM9/5/08
to
On Sep 4, 9:46 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> Ian Collins wrote:
> > Uwe Schmitt wrote:
> >> Which compilers do you use and how do you use them ?

> >> If you use the gnu compiliers, you should use

> >> g++ -c cpplib.cpp

> >> and then

> >> gcc cprogram.c cpplib.o

> > That's very unlikely to work. The main program must be


> > compiled and linked as C++.

> So, more likely it should be

> g++ -c cpplib.cpp
> gcc -c cprogram.c
> g++ cprogram.o cpplib.o -o cprogram

If the main() is in cprogram.c, that still isn't guaranteed to
work. main() must be compiled as C++. (But since not doing so
is undefined behavior, it's possible that it works anyway, with
some implementations.)

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Kanze

unread,
Sep 5, 2008, 6:02:07 AM9/5/08
to
On Sep 5, 4:52 am, "northern_RATT" <n...@none.net> wrote:
> <snip>> I need to be able to mix C and C++.
> > The main program is written in C and needs to access C++
> > code. To be more specific it's a user defined function in
> > fluent, but this should not be relevant.

> > I've allready read that i need to use the extern "C"
> > construction but i don't seem to be doing it right.

> </snip>

> OK. Pardon a rank amature who only lurks here, BUT....
> This looks like backwards logic to me. I thought that
> 'extern C' is a way for C++ code to call undecorated C code(?)

No. 'extern "C"' tells the compiler to use C linkage, period.
A C++ function can be declared 'extern "C"', in which case, it
uses C linkage (but is C++ in every other way), and can be
called from a C program.

The classical example is the function passed to things like
pthread_create (Unix) or CreateThread (Windows); since this
function is called from C code, it must be 'extern "C"'.

> Not the otherway around!
> Not that I have ever needed to face this, but I thought that C
> calling C++ code needs some type of wrapper?

And how would you implement the wrapper? If you can't call C++
from C, you can't implement it in C, and if you implement it in
C++, you couldn't call it from C.

Typically, C++ code does require a wrapper, because it is using
argument types which C can't handle; the wrapper takes care of
any necessary type conversions. But thw wrapper itself is also
C++.

Uwe Schmitt

unread,
Sep 5, 2008, 1:29:08 PM9/5/08
to

But all names cpplib.o are plain, because we used 'extern "C"' in
'function()'s declaration. So the linker will see no C++ mangled
symbolnames during linking.
Did I miss something ? Why should I use C++ compiler for compiling and
linking
a C program with some object file which looks like a C-object file ?

Greetings, Uwe


Sherm Pendley

unread,
Sep 5, 2008, 1:35:16 PM9/5/08
to
Uwe Schmitt <rockspo...@googlemail.com> writes:

> On 4 Sep., 21:10, Ian Collins <ian-n...@hotmail.com> wrote:
>> Uwe Schmitt wrote:
>>
>> > Which compilers do you use and how do you use them ?
>>
>> > If you use the gnu compiliers, you should use
>>
>> >      g++ -c cpplib.cpp
>>
>> > and then
>>
>> >      gcc cprogram.c cpplib.o
>>
>> > Greetings, Uwe
>>
>> That's very unlikely to work.  The main program must be compiled and
>> linked as C++.
>
> But all names cpplib.o are plain, because we used 'extern "C"' in
> 'function()'s declaration. So the linker will see no C++ mangled
> symbolnames during linking.
> Did I miss something ?

The public symbols exported by cpplib.o and used in cprogram aren't
the problem. The problem is that cpplib.o probably needs to link to
libstdc++. That happens by default when you use g++, but not with
gcc.

sherm--

--
My blog: http://shermspace.blogspot.com
Cocoa programming in Perl: http://camelbones.sourceforge.net

James Kanze

unread,
Sep 5, 2008, 2:24:01 PM9/5/08
to
On Sep 5, 7:29 pm, Uwe Schmitt <rocksportroc...@googlemail.com> wrote:
> On 4 Sep., 21:10, Ian Collins <ian-n...@hotmail.com> wrote:
> > Uwe Schmitt wrote:

> > > Which compilers do you use and how do you use them ?
> > > If you use the gnu compiliers, you should use

> > > g++ -c cpplib.cpp

> > > and then

> > > gcc cprogram.c cpplib.o

> > That's very unlikely to work. The main program must be compiled and
> > linked as C++.

> But all names cpplib.o are plain, because we used 'extern "C"' in
> 'function()'s declaration. So the linker will see no C++ mangled
> symbolnames during linking.

So?

> Did I miss something ? Why should I use C++ compiler for
> compiling and linking a C program with some object file which
> looks like a C-object file ?

The C++ standard is quite clear: main() must be compiled as C++.
Depending on the compiler, it might work if this isn't the case,
or it might not, or somethings might work, and others not. In
particular, with some compilers, there's a very good chance that
static variables won't be initialized correctly if main isn't
compiled as C++.

And mangling really has not got much to do with the problem.

James Kanze

unread,
Sep 5, 2008, 2:25:36 PM9/5/08
to
On Sep 5, 7:35 pm, Sherm Pendley <spamt...@dot-app.org> wrote:

> Uwe Schmitt <rocksportroc...@googlemail.com> writes:
> > On 4 Sep., 21:10, Ian Collins <ian-n...@hotmail.com> wrote:
> >> Uwe Schmitt wrote:
> >> > Which compilers do you use and how do you use them ?

> >> > If you use the gnu compiliers, you should use

> >> > g++ -c cpplib.cpp

> >> > and then

> >> > gcc cprogram.c cpplib.o

> >> That's very unlikely to work. The main program must be


> >> compiled and linked as C++.

> > But all names cpplib.o are plain, because we used 'extern
> > "C"' in 'function()'s declaration. So the linker will see no
> > C++ mangled symbolnames during linking. Did I miss
> > something ?

> The public symbols exported by cpplib.o and used in cprogram
> aren't the problem. The problem is that cpplib.o probably
> needs to link to libstdc++. That happens by default when you
> use g++, but not with gcc.

The problem is also that static variables have to be
initialized; some compilers do this by generating special code
in main. Of course, if main wasn't compiled with a C++
compiler, it won't have that special code.

Jerry Coffin

unread,
Sep 5, 2008, 11:17:20 PM9/5/08
to
In article <48c0dbfe$0$17346$426a...@news.free.fr>,
michael...@free.fr says...

[ ... ]

> Most c++ compiler support C99 unless you disable it in the command line.

Really? All the C++ compilers I have handy seem to reject the following
perfectly legal bit of C99 code:

union {
char birthday[9];
int age;
float weight;
} people = { .age = 14 };

Even Comeau (which will accept it as C99 code) rejects it as C++ code
(quite rightly, I might add, since it's ill formed C++ code, and I don't
believe C++ 0x will allow it either).

Every other compiler I have handy (Microsoft, Digital Mars, gnu) rejects
it as either C or C++. gnu has a '-std=c99' flag, but appears to
implement little enough of C99 that it doesn't accept this even with
that flag.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Uwe Schmitt

unread,
Sep 6, 2008, 7:46:46 AM9/6/08
to
> James Kanze (GABI Software)             email:james.ka...@gmail.com
> hing nConseils en informatique orientée objet/

>                    Beratung in objektorientierter Datenverarbeitung
> 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

thanks, I learned something new :-)

Greetings, Uwe

Ben Bacarisse

unread,
Sep 6, 2008, 9:28:07 AM9/6/08
to
Jerry Coffin <jco...@taeus.com> writes:

Recent versions of gcc accept it.

--
Ben.

Ian Collins

unread,
Sep 6, 2008, 4:38:23 PM9/6/08
to
gcc also accepts VLAs, but I doubt any other C++ compiler would.

--
Ian Collins.

Ben Bacarisse

unread,
Sep 6, 2008, 6:54:07 PM9/6/08
to
Ian Collins <ian-...@hotmail.com> writes:

I mean gcc accepts it when invoked with '-std=c99'. Jerry Coffin said
it did not. I am reporting that at least some recent versions do (as
they must if they want to compile C99).

For the record, the same gcc correctly rejects (or at least diagnoses)
VLAs when invoked as a conforming C++ compiler. The presence of a
default mixed mode where a compiler accept some odd half-language plus
extensions is unfortunate but common.

--
Ben.

Ian Collins

unread,
Sep 6, 2008, 7:10:19 PM9/6/08
to
Ben Bacarisse wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>
>> Ben Bacarisse wrote:
>>> Jerry Coffin <jco...@taeus.com> writes:

>>>>> Most c++ compiler support C99 unless you disable it in the command line.
>>>> Really? All the C++ compilers I have handy seem to reject the following
>>>> perfectly legal bit of C99 code:
>>>>
>>>> union {
>>>> char birthday[9];
>>>> int age;
>>>> float weight;
>>>> } people = { .age = 14 };
>>>>

>>> Recent versions of gcc accept it.


>>>
>> gcc also accepts VLAs, but I doubt any other C++ compiler would.
>
> I mean gcc accepts it when invoked with '-std=c99'. Jerry Coffin said
> it did not. I am reporting that at least some recent versions do (as
> they must if they want to compile C99).
>
> For the record, the same gcc correctly rejects (or at least diagnoses)
> VLAs when invoked as a conforming C++ compiler. The presence of a
> default mixed mode where a compiler accept some odd half-language plus
> extensions is unfortunate but common.
>

That (gcc correctly rejects VLAs in C++ mode) is good. One of my worst
poring form gcc to standard C++ nightmares was scores of gcc VLAs.

--
Ian Collins.

Jerry Coffin

unread,
Sep 6, 2008, 10:37:01 PM9/6/08
to
In article <878wu5i...@bsb.me.uk>, ben.u...@bsb.me.uk says...

[ ... ]

> Recent versions of gcc accept it.

I'm glad to hear that. What I was using isn't exactly current, but it's
not terribly old either -- it's good to hear that they're apparently
making a real attempt at C99 compliance (finally...)

Michael DOUBEZ

unread,
Sep 8, 2008, 6:07:42 AM9/8/08
to
Jerry Coffin a écrit :

> In article <48c0dbfe$0$17346$426a...@news.free.fr>,
> michael...@free.fr says...
>
> [ ... ]
>
>> Most c++ compiler support C99 unless you disable it in the command line.
>
> Really? All the C++ compilers I have handy seem to reject the following
> perfectly legal bit of C99 code:
>
> union {
> char birthday[9];
> int age;
> float weight;
> } people = { .age = 14 };
>

True. I have overly generalized.
I was thinking of VLAs which tends to creep in so often. This code is
however accepted by my IAR c++ compiler.

More compliant c++ compiler will hopefully reject this code. But I guess
one could tweak them into accepting it.

--
Michael

0 new messages