在我正在编写的应用程序中,我正在从我编写的共享库中动态加载对象。
直到虚拟功能发挥作用的这一点。这意味着我可以轻松调用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已设置。
我真的很感激任何帮助。
答案 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)
会发生这种情况(尽管静态方法可以正常工作)。因此,在完成对象之前,不应该关闭库句柄。