C ++:动态共享库中的虚函数会产生段错误

时间:2011-11-10 15:26:36

标签: c++ eclipse dll segmentation-fault eclipse-cdt

在我正在编写的应用程序中,我正在从我编写的共享库中动态加载对象。

直到虚拟功能发挥作用的这一点。这意味着我可以轻松调用getter和setter,但在尝试调用覆盖虚拟基类函数的函数时,我立即遇到分段错误。我目前的想法已经不多了,因为这会发生在我项目中的每个类(层次结构)中。

在应用程序内创建对象时,可以成功调用这些函数,而不是使用动态加载或共享库。

我怀疑在我这方面存在概念错误或某种编译/链接错误。

类层次结构如下所示:

BaseClass.h:

class BaseClass : public EvenMoreBaseClass { public: virtual bool enroll(const shared_ptr<string> filepath) = 0; }

Derived.h:

class Derived : public BaseClass { bool enroll(const shared_ptr<string> filepath); }

Derived.cpp:

bool Derived::enroll(const shared_ptr<string> filepath) { cout << "enroll" << endl; }

(此处包含和命名空间)

应用程序加载库并获取指向BaseClass对象的(共享)指针(应用程序包含BaseClass.h)。除虚拟功能外,所有功能都可以执行。

开发在Eclipse CDT中完成。目前所有内容都在一个具有不同构建配置的项目中(应用程序的.cpp在共享库的配置中被禁用,反之亦然)。编译器是g ++ 4.4。层次结构中的所有.o文件都与库链接,-shared已设置。

我真的很感激任何帮助。

3 个答案:

答案 0 :(得分:0)

构建配置中设置的项目之间的类型大小是否有任何差异?

[更新]

当一个项目的类型如short和long定义为与另一个项目的大小不同时,我遇到了类似的问题,并且包含这些类型的类通过相同的头文件引用。一个项目将第二个短路放在字节2,另一个项目认为它位于字节4。

我也遇到了不同填充值的问题。一个项目将奇数字符填充到4字节边界,另一个项目将填充到8字节边界。

虚拟函数指针可能也是如此,也许一个项目适合32位,另一个项目需要64位。

答案 1 :(得分:0)

确保使用 exact 相同的编译器设置编译dll和可执行文件。如果它们不同,编译器可能会在可执行文件中生成与dll期望的内容不匹配的代码,反之亦然ODR违规。

请注意,标准库类型(例如std :: string和std :: shared_ptr)在调试配置中可能具有不同的布局,并且也可以在编译器版本之间进行更改(甚至来自同一供应商)。

通常,您需要小心使用跨dll边界的类。通常建议仅处理内置类型和无状态接口。

答案 2 :(得分:0)

也许这是一个非常晚的答案,但我发现了同样的行为,如果你在访问虚拟方法之前使用dlclose(handle)会发生这种情况(尽管静态方法可以正常工作)。因此,在完成对象之前,不应该关闭库句柄。