使用c ++动态链接困境

时间:2009-09-30 21:11:27

标签: c++ linux shared-libraries

运行整个过程将导致以下错误:

Cannot open library "./libexamplefilter.so" ./libexamplefilter.so: undefined symbol: _ZTI10BaseFilter

由于代码非常小且可以理解,您应该能够立即理解它。 谁知道什么是错的?

我是否应该将create()声明为extern“C”void * create(void); 并在之后转换void指针而不是直接尝试链接c ++符号?

下一步

使用-Wl,-export-dynamic后,它告诉我:

Cannot load library symbols "./libexamplefilter.so" ./libexamplefilter.so: undefined symbol: create

呃,我是否必须在那里提供一个错误的c ++ - 名称,而不是“dlsym(handle,”create“)”。大概。是否有一种优雅的方式来做到这一点?

答案是声明create()extern“C”...创建.... 这非常有效。 问题解决了。感谢您的帮助和耐心。

5 个答案:

答案 0 :(得分:4)

编译主可执行文件时,需要使用链接器选项“export-dynamic”。

通常,主可执行文件不会导出其符号以供动态链接器使用(除非符号由参与链接的某个共享库使用),这意味着如果您的库调用回主exe,它将无法加载。

当您尝试使用虚方法和其他一些情况对类进行子类化时,会发生这种情况。如果你试图这样做,那就失败了。

因此,在关联主程序时,请添加-Wl,-export-dynamic,这样就可以了。

答案 1 :(得分:1)

我在探索插件架构时遇到了这个问题。您的错误不在您的主要内容中,而在于您如何链接libexamplefilter.so。不幸的是,我没有代码(或内存!)来告诉你如何解决它,但我认为你需要在单独的.so中声明你的BaseFilter类,并将libexamplefilter和你的应用程序链接到.so。

答案 2 :(得分:1)

您的.so和应用程序之间的_ZTI10BaseFilter符号(类的类型信息)的可见性可能不匹配。如果你跑

,你会得到什么?
nm <target> | grep _ZTI10BaseFilter

在包含BaseFilter的每个target上,即您的动态库和可执行文件?

答案 3 :(得分:1)

  

我是否应该将create()声明为extern“C”void * create(void);并在之后转换void指针而不是直接尝试链接c ++符号?

我个人会推荐这个,即使这不是真正的问题。在类似UNIX的操作系统中,名称修改是非常标准的 - 使用英特尔ABI和所有操作系统 - 但它不是真正的标准,Windows使用不同的名称修改方案(因此将应用程序移植到Windows需要更改这些字符串) ,我不确定OS X是否在板上(因此移植到OS X可能需要更改这些字符串)。

答案 4 :(得分:0)