Ramon F Herrera said:
The problem was fixed by the extern "C" statement, Josh.
Notice that you can wrap several declarations in a block:
extern "C"{
#include <c_code.h>
int foo(int);
}
How about the opposite, how should I refer to to an extern C++
function?
Let me guess:
extern "C++"
If that was that easy!
Since a lot of C code can be compiled by C++ compilers, the easiest is
to consider the C code as C++ code, and just call the other C++
functions without further ado.
However, if you have non-C++ conciscous C code, you might have to
review it and modify it slightly to avoid the things that are excluded
by C++. For example you cannot use the identifier 'new' in C++ code
since it's a keyword, so any C code that would it would have to be
edited. There are a number of similar gotchas.
Technically, the problem is that C++ function names are mangled, and
this mangling is implementation dependant! The signature of the
function is encoded into the external name of C++ functions.
So a C++ function such as int foo(int,char*); will actually be named
something like __Z3fooiPc in the object file.
From C code, compiled with a C program, you could call it as:
// C code:
extern int _Z3fooiPc(int i,char* c);
int f(){
char a[]="abc";
_Z3fooiPc(3,a);
}
Not funny.
The solution is to define C wrapper functions, in C++ (ie. you still
need the C++ compiler).
-------------------------------- c.cxx
// A C++ function:
int bar(int i,char* c){
return(c
);
}
// A C++ function whose name won't be mangled:
extern "C" int foo(int i,char* c){
return(bar(i,c));
}
---------------------------------
% g++ -c -o c.o c.cxx && nm c.o
00000000 T __Z3bariPc
00000000 A __Z3bariPc.eh
00000014 T _foo
00000000 A _foo.eh
Notably, in the case of C++ objects, your wrapper will have to
explicitely pass the 'this' parameter:
-------------------------------- o.cxx
// A C++ class:
class Example {
int i;
public:
Example(int aI):i(aI){}
int foo(char* c){
return(c[this->i]);
}
};
// A C wrapper over the C++ class:
extern "C"{
typedef void* ExampleP;
ExampleP Example_new(int aI){ return new Example(aI); }
Example_foo(ExampleP that,char* c){ return(((Example*)that)->foo(c)); }
}
---------------------------------
% g++ -c -o o.o o.cxx && nm o.o
0000006c s EH_frame1
0000002c T _Example_foo
00000000 A _Example_foo.eh
00000000 T _Example_new
000000d0 S _Example_new.eh
00000056 S __ZN7Example3fooEPc
000000ac S __ZN7Example3fooEPc.eh
00000046 S __ZN7ExampleC1Ei
00000088 S __ZN7ExampleC1Ei.eh
U __Znwm
U ___gxx_personality_v0