Search code examples
c++clinkerstatic-linking

How to embed a C++ library in a C library?


I have a question related to embedding one library in another.

I have a code that is pure C and my users rely on that, they don't want to depend on C++ libraries. However, the need arose to embed a 3rd party library (ICU) into mine. None of the ICU functions would be exported, they would only be used internally in my library. Unfortunately ICU is a C++ library, though it does have a C wrapper. ICU does not use exceptions, but it does use RTTI (abstract base classes).

The question is how could I create my static library so that

  1. ICU is embedded in my library (all references to ICU functions are resolved within my library)
  2. all references to libstdc++ are also resolved and the necessary code is embedded into my library
  3. if a user does not even have libstdc++ installed on their system things work just fine
  4. if a user does happen to use my library within a C++ project then there are no conflicts with whatever libstdc++ (presumably the system libstdc++) he uses.

Is this possible at all? The targeted platforms are pretty much everything: windows (there my library is dynamic), and all sort of unix versions (linux, solaris, aix, hpux - here my library needs to be static).

gcc-4.5 and later does have --static-libstdc++, but as far as I understand it is only for creating shared libs or executables, and not static libs.

Thanks for any help!


Solution

  • The solution to this problem is pretty simple, but may not fall inside the parameters you have set.

    The simple rules are:

    1. You can dynamically link a C++ library to a C caller, but you have to wrap the library inside an extern C layer. You design the extern C API and implement it using C++ internals, which are forever hidden from view. [You can also use COM or .NET to do this on Windows.]
    2. You cannot statically link a C++ library to a C caller. The libraries are different and the calling sequences/linker symbols are different. [You often can't even statically link between different versions of the same compiler, and almost never between different compilers.]

    In other words, the solution is simple: use dynamic linking. If that's not the right answer, then I don't think there is one.

    Just to make things interesting, you can even implement your own plug-in architecture. That's just another name for dynamic linking, but you get to choose the API.


    Just to be clear, the only viable portable option I can see is that you link ICU inside its own dynamic library (DLL or SO). Its symbols, C++ libs, RTTI and exceptions all stay inside that. Your static lib links to the ICU dynamic lib by extern C. That's exactly how much of Windows is built: C++ inside DLL, extern C.

    You can debug across the boundary, but you cannot export type information. If you need to do that, you will have to use a different API, such as .NET or COM.