【问题标题】:C++: Virtual functions in dynamic shared library produce segfaultC++:动态共享库中的虚函数产生段错误
【发布时间】:2011-11-10 15:26:36
【问题描述】:

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

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

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

我怀疑是概念错误或某种编译/链接错误。

类层次结构如下所示:

BaseClass.h:

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

派生的.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。

非常感谢任何帮助。

【问题讨论】:

  • 你在调试器中运行过这个吗?
  • 我有,但是当我第二次尝试访问虚拟功能时,我得到了一个段错误。我在虚函数的名称上设置了断点,但在库中从未成功调用过。

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


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      在构建配置中设置的项目之间的类型大小会有所不同吗?

      [更新]

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

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

      同样的情况也适用于虚函数指针,也许一个项目适合它们为 32 位,另一个项目期望它们为 64 位。

      【讨论】:

      • 它们包含相同的文件,我通常编译这两种配置。这可能是一个问题,例如一个生成与另一个生成不同的 .o 文件,导致库和应用程序的类型不同?还是您的意思是其他一些类型的大小?
      • 感谢您的更新,当我回到这个问题时,我会检查一下 - 因为动态加载在这个项目中是一个“不错的”功能,所以我将首先专注于应用程序逻辑。
      猜你喜欢
      • 2021-04-13
      • 2023-03-12
      • 2014-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多