Reputation: 286
I've a client that shipped a C++ code that I desesperately need to use in a really big project written in C.
The problem is: I can't rewrite that C++ code to be in C ... would be too easy, I don't have the IP on this code and the client has to maintain the code.
I also can't link my really big project in C using g++: this would break things!
I tried to turn the C++ code into a lib, exporting a C-Style interface (with extern "C", encapsulating classes into structures) but I have a problem while linking this lib to my project ... (remember, can't use g++ to link) : I end-up with undefined references to almost all of the STL In despair, I statically linked the STL to the C/C++ wrapper lib I made but this didn't change anything.
I don't know much about C++ but I don't want to be writting a C++ STL/C wrapper for this particular use case.
right now, I've made a binary from the C++ code and I call it using fork/exec in my C code ... this is a really bad solution I'd like to avoid.
If anyone has a clue/direction/hint, That would be much appreciated.
Thx, Guillaume.
Upvotes: 8
Views: 353
Reputation: 1
You could link the shared C++ library with g++
and link that with your program with gcc
, something like:
g++ -Wall -O -c -fPIC lib++/src1.cc -o lib++/src1.pic.o
g++ -Wall -O -c -fPIC lib++/src2.cc -o lib++/src2.pic.o
## etc, compile each C++ file of the library
##
## then link the library with standard C++ library, etc...
g++ -shared lib++/src*.pic.o -lstdc++ -o lib++/libpp.so
Then use that shared library in your C project:
gcc -Wall -O -c src/file1.c -o src/file1.o
gcc -Wall -O -c src/file2.c -o src/file2.o
## link your program with lib++/libpp.so
gcc src/fil*.o -L lib++ libpp.so -lotherlibs -o yourprog
Remember that you can link a shared library with other shared libraries.
Of course, you'll want to modify your building system, e.g. your Makefile
-s, to do the above commands.
Remember also that some functions have the constructor
function attribute (and C++ compilation uses that a lot, for construction of static C++ instances). These functions are running before main
; symmetrically, function with the destructor
attribute are running after main
. For dynamically loaded libraries loaded by dlopen
, constructor functions are run during dlopen
and destructor functions during dlclose
.
As several others pointed out, beware of C++ exceptions thrown across a C boundary
Upvotes: 1
Reputation: 129524
The real answer to this question, aside from Azzy's answer, is really a question of what you need to do to call your c++ code.
Using fork may be a good idea, but in general, I'd say that's not the right solution unless the C++ code takes some significant amount of time to execute in the first place [in which case the fork/exec overhead is small enough to not matter].
The right solution, in general, is to write a small interface between your program and the C++ code, using a C interface (and the extern "C"
wrappers - don't forget to use #ifdef __cplusplus
in the header that defines the interface, around the extern "C"
so that you can use the same header file in both the C++ interface implementation and the calling C code).
Also beware of exceptions. You MUST NOT call C++ code that throws exceptions from C - they must be handled in C++, or BAD THINGS will happen (exactly what kind of bad things is not determinable - random code may be executed, or the system crashes, or some random erroneous output occurs, etc)
Upvotes: 3