如何在不需要stdc ++链接的情况下将C程序连接到C ++库?

时间:2012-01-26 13:51:35

标签: c++ c linker

我正在尝试将一些代码添加到需要使用C ++库的更大的C项目中。

C ++库使用标记为extern“C”的函数提供了一个包装器,可以访问库的功能

//Some C++ library
//mywrapper.h
#ifdef __cplusplus
extern "C" {
#endif

void wrapperFunction1( int width );
void wrapperFunction1( int height);
#ifdef __cplusplus
} // extern "C"
#endif

这可以毫无问题地编译g ++。

在制作C程序并包含mywrapper.h时,我不断发现引用vtable和cxa_pure_virtual的链接器错误:

undefined reference to `vtable for __cxxabiv1::__class_type_info'
undefined reference to `__cxa_pure_virtual'

在测试中,这些错误消失了,并且在我添加stdc ++库时允许程序编译,但这不是大C项目的选项。有没有办法编译C程序来访问没有这些错误和没有stdc ++的C ++库?并且错误的交易是指在C ++库内部并且未在mywrapper.h中引用的模块,那么为什么C程序甚至试图引用它们呢?

5 个答案:

答案 0 :(得分:8)

C ++库依赖于标准C ++库(libstdc ++,链接器的-lstdc++选项,如果通过g++运行链接器则默认)。这是事实。没有什么可以做的。克服它。

包装器标头不引用这些符号,但库中的实际目标文件执行。因此需要定义它们,定义它们的方法是包含标准C ++库。

请注意,如果包装的库本身是动态的,它将知道它的依赖性,您不必动态指定与libstdc ++的链接。

答案 1 :(得分:3)

这是你要包装的C ++库需要stdc ++,而不是你的包装器。

您已经包装了C ++函数,以便它们可以从C中调用,但它们仍然在内部使用依赖于C ++标准库的库。如果您没有提供stdc ++,那么您正在使用的库将缺少其实现的一部分。除非你重写C ++库,否则无法绕过它。

答案 2 :(得分:1)

通常,C ++代码需要一定程度的运行时支持来处理特定的C ++特性。例如,有一个处理dynamic_cast<>()的库函数。即使您不使用任何标准C ++库,您也需要这种语言支持libray。它通常包含在标准C ++库中,但专门针对gcc,此库可单独使用。也就是说,你可能会因为不包括libstdc++而逃脱,但你不会逃脱包括这个库。目前我无法知道它是如何被调用的。我认为这是-lcxxabi,但我不确定。

答案 3 :(得分:1)

完全有效的不包括libstdc++一些警告。根据你在C ++代码中所做的事情(或者在这种情况下你正在包装的库),它可能希望底层运行时提供某些功能:

  • 就像你提到的那样,RTTI信息
  • __cxa_pure_virtual如果你有未实现的纯虚函数(例如,在纯抽象类中)
  • main()之前调用构造函数,在
  • 之后调用析构函数

这不仅发生在您不包含libstdc++库的情况下,而且还发生在已删除的库自定义版本上。

例如,Rowley Crossworks for ARM(嵌入式系统工具链)建议您自己编写__cxa_pure_virtual错误处理程序。

答案 4 :(得分:0)

好的,我做了更多的研究,我偶然发现了答案,我有两个问题,首先是错误信息:

./lib.so: undefined reference to vtable for __cxxabiv1::__si_class_type_info' 
./lib.so: undefined reference to `vtable for __cxxabiv1::__class_type_info'

这些与C ++的运行时类型信息或rtti有关。用“-fno-rtti”编译库消除了这些错误。

第二个问题是:

./lib.so: undefined reference to __cxa_pure_virtual'

原因是C编译器无法处理来自C ++的虚函数。使用extern“C”创建存根函数消除了错误并允许项目编译。

我仍然在确认库是否正常工作,但这些更改似乎已经纠正了错误。

感谢大家的帮助。