extern "C"

K

Karel Van Laer

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
 
K

Karel Van Laer

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
 
U

Uwe Schmitt

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
 
I

Ian Collins

Uwe said:
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++.
 
N

northern_RATT

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
 
A

Alexander Dong Back Kim

</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

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
 
M

Michael DOUBEZ

Alexander Dong Back Kim a écrit :
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.
 
J

James Kanze

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.)
 
J

James Kanze

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++.
 
U

Uwe Schmitt

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 ? 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
 
S

Sherm Pendley

Uwe Schmitt said:
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--
 
J

James Kanze

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.
 
J

James Kanze

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.
 
J

Jerry Coffin

[ ... ]
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.
 
U

Uwe Schmitt

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.

--
James Kanze (GABI Software)             email:[email protected]
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
 
B

Ben Bacarisse

Jerry Coffin said:
[ ... ]
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.

Recent versions of gcc accept it.
 
I

Ian Collins

Ben said:
Jerry Coffin said:
[ ... ]
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.

Recent versions of gcc accept it.
gcc also accepts VLAs, but I doubt any other C++ compiler would.
 
J

Jerry Coffin

[email protected] says... said:
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...)
 
M

Michael DOUBEZ

Jerry Coffin a écrit :
[ ... ]
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.
 
M

Michael DOUBEZ

Jerry Coffin a écrit :
[ ... ]
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top