granquet
granquet

Reputation: 286

Use C++ code in a C project

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

Answers (2)

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

Mats Petersson
Mats Petersson

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

Related Questions