如何在C库中嵌入c++库?

时间:2022-09-01 16:53:43

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

我有一个纯C的代码,我的用户依赖它,他们不想依赖c++库。然而,需要将第三方图书馆(ICU)嵌入到我的数据库中。没有一个ICU函数会被导出,它们只会在我的库中内部使用。不幸的是,ICU是一个c++库,尽管它有一个C包装器。ICU不使用异常,但它使用RTTI(抽象基类)。

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. ICU嵌入到我的库中(对ICU函数的所有引用都在我的库中解析)
  3. all references to libstdc++ are also resolved and the necessary code is embedded into my library
  4. 所有对libstdc++的引用也被解析,必要的代码被嵌入到我的库中
  5. if a user does not even have libstdc++ installed on their system things work just fine
  6. 如果用户没有在系统上安装libstdc++,那么就可以正常工作。
  7. 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.
  8. 如果用户碰巧在c++项目中使用我的库,那么无论使用什么libstdc++ +(可能是系统libstdc++ +),都不会发生冲突。

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

这可能吗?目标平台几乎是所有的东西:windows(我的库是动态的)和所有类型的unix版本(linux、solaris、aix、hpux——这里我的库需要是静态的)。

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.

gcc-4.5和以后的版本确实有——static-libstdc++,但是据我所知,它只用于创建共享的lib或可执行的,而不是静态的libs。

Thanks for any help!

感谢任何帮助!

2 个解决方案

#1


4  

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. 您可以动态地将一个c++库链接到一个C调用者,但是您必须将库封装在一个外部C层中。您设计了extern C API并使用c++内部构件(永远隐藏在视图之外)来实现它。[你也可以在Windows上使用COM或。net来实现这一点。]
  3. 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.]
  4. 您不能静态地将一个c++库链接到一个C调用方。库是不同的,调用序列/链接符号是不同的。[您经常不能在同一个编译器的不同版本之间进行静态链接,而且几乎不可能在不同的编译器之间进行链接。]

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.

为了使事情变得有趣,您甚至可以实现自己的插件体系结构。这只是动态链接的另一个名称,但是您可以选择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.

要清楚的是,我能看到的唯一可行的可移植的选项是您将ICU链接到它自己的动态库中(DLL或SO)。它的符号,c++ libs, RTTI和exception都在其中。您的静态库通过extern C链接到ICU动态库的链接,这正是构建Windows的程度:c++中的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.

您可以在边界上进行调试,但是不能导出类型信息。如果需要这样做,就必须使用不同的API,如. net或COM。

#2


0  

I don't know if this will work, but let me at least suggest that you try it!

我不知道这是否可行,但至少让我建议你试试!

The excellent LLVM project (origin of clang compiler) has many front-ends and back-ends for different languages, such as C++ and C. And according to this S.O. question it should be possible for LLVM to compile C++ into C which in turn can be compiled as normal.

优秀的LLVM项目(clang编译器的起源)对于不同的语言有很多前端和后端,比如c++和C。根据这个S.O.的问题,LLVM应该有可能将c++编译成C语言,而C语言又可以正常编译。

I imagine this route is a bumpy one, but if it works, it might solve your problem without the need to link dynamically. It all depends on if ICU will compile with LLVM C++.

我认为这条路是崎岖不平的,但如果可行的话,它可能会解决你的问题,而不需要动态链接。这完全取决于ICU是否使用LLVM c++编译。

If you do decide to give it a go, please let us know how you fare!

如果你决定试一试,请告诉我们你的情况!

#1


4  

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. 您可以动态地将一个c++库链接到一个C调用者,但是您必须将库封装在一个外部C层中。您设计了extern C API并使用c++内部构件(永远隐藏在视图之外)来实现它。[你也可以在Windows上使用COM或。net来实现这一点。]
  3. 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.]
  4. 您不能静态地将一个c++库链接到一个C调用方。库是不同的,调用序列/链接符号是不同的。[您经常不能在同一个编译器的不同版本之间进行静态链接,而且几乎不可能在不同的编译器之间进行链接。]

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.

为了使事情变得有趣,您甚至可以实现自己的插件体系结构。这只是动态链接的另一个名称,但是您可以选择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.

要清楚的是,我能看到的唯一可行的可移植的选项是您将ICU链接到它自己的动态库中(DLL或SO)。它的符号,c++ libs, RTTI和exception都在其中。您的静态库通过extern C链接到ICU动态库的链接,这正是构建Windows的程度:c++中的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.

您可以在边界上进行调试,但是不能导出类型信息。如果需要这样做,就必须使用不同的API,如. net或COM。

#2


0  

I don't know if this will work, but let me at least suggest that you try it!

我不知道这是否可行,但至少让我建议你试试!

The excellent LLVM project (origin of clang compiler) has many front-ends and back-ends for different languages, such as C++ and C. And according to this S.O. question it should be possible for LLVM to compile C++ into C which in turn can be compiled as normal.

优秀的LLVM项目(clang编译器的起源)对于不同的语言有很多前端和后端,比如c++和C。根据这个S.O.的问题,LLVM应该有可能将c++编译成C语言,而C语言又可以正常编译。

I imagine this route is a bumpy one, but if it works, it might solve your problem without the need to link dynamically. It all depends on if ICU will compile with LLVM C++.

我认为这条路是崎岖不平的,但如果可行的话,它可能会解决你的问题,而不需要动态链接。这完全取决于ICU是否使用LLVM c++编译。

If you do decide to give it a go, please let us know how you fare!

如果你决定试一试,请告诉我们你的情况!