【问题标题】:No symbol in shared library of implemented parent method已实现父方法的共享库中没有符号
【发布时间】:2015-07-23 10:06:51
【问题描述】:

我有一个类 AbsAlgorithm,它有 3 个虚拟方法:

class AbsAlgorithm
{
public:
    //..... other methods
    virtual void run() = 0;
    virtual bool init(TestCase&) = 0;
    virtual bool done() = 0;
};

我创建了一个静态库libAlgatorc.a,其中包含这个类。

我还有 SortingAbsAlgorithm 类,它继承自 AbsAlgorithm 并覆盖方法 runinitdone

class SortingAbsAlgorithm : public AbsAlgorithm
{
public:
    void run()
    {
        execute(...);
    }

    bool done()
    {
        return result;
    }
}

当我创建一个包含此类(和其他一些类)的共享库时,我在共享库中没有 SortingAbsAlgorithm::runSortingAbsAlgorithm::initSortingAbsAlgorithm::done 的符号。为什么?

我这样创建共享库:

g++ -std=gnu++11 -fPIC SortingAbsAlgorithm.cpp SortingTestSetIterator.cpp SortingTestCase.cpp  -shared -o libProject.so -Wl,--whole-archive -lAlgatorc -Wl,--no-whole-archive

【问题讨论】:

  • 你定义了那些纯虚函数吗?如果它们只被声明而不是定义,那么库中可能会输出什么?或者您是在询问SortingAbsAlgorithm 中的覆盖吗? (不清楚您要问的是哪些符号)。
  • 即使在您编辑之后,仍然不清楚您要询问的是哪些符号。您是否希望看到AbsAlgorithm::runSortingAbsAlgorithm::run 或两者的符号?
  • 我期待看到 SortingAbsAlgorithm::run。我想不会有任何 AbsAlgorithm::run 符号
  • 好吧,那你的问题自相矛盾,因为你说“这是因为这个方法是纯虚方法吗?”SortingAbsAlgorithm::run不是纯虚方法
  • 好的。我把那句话删了。 SortingAbsAlgorithm::run 符号不在我的共享库中可能有什么问题?

标签: c++ linker shared-libraries static-libraries


【解决方案1】:

除非您为其编写定义,否则您不会在基类中看到纯虚函数的任何符号,因为编译器不可能为不存在的定义输出任何符号。

您也不会在派生类中看到任何覆盖定义,除非您调用它们,并且可能只有在您调用它们并在没有优化的情况下编译时。

这是因为它们被定义为内联函数(因为您在类主体中定义了它们),因此根据 C++ 标准中的 [dcl.fct.spec]/4,编译器知道这些函数的任何其他调用者在其他目标文件也可以看到函数定义,所以编译SortingAbsAlgorithm.cpp时不需要发出extern符号。

如果您想确保编译器输出这些函数的定义,则不要将它们定义为内联函数。或者,如果您在库中有代码构造 SortingAbsAlgorithm 的实例,这也将确保库包含虚函数的符号(但不包含在库中未调用的任何其他内联函数)。

【讨论】:

  • 所以基本上我可以调用它们,但我在共享库中看不到它们。如果我在主程序中加载这个动态库并创建类 SortingAbsAlgorithm 的实例,我可以调用方法 run、done 和 init?这是正确的吗?
  • 如果您的主程序看到SortingAbsAlgorithm 的定义,那么它将能够调用它们,因为这些函数是内联定义的,您的主程序可以看到它们的定义。如果主程序可以创建类的实例,它必须能够看到它的定义,所以它也能看到函数。
猜你喜欢
  • 2021-03-21
  • 1970-01-01
  • 2012-02-07
  • 2012-09-03
  • 1970-01-01
  • 2023-03-13
  • 2019-08-02
  • 2017-08-02
  • 1970-01-01
相关资源
最近更新 更多