C++共享库中基类的未定义符号错误

5

我使用g++ -shared ...编译了以下代码,生成了一个共享库:

class Foo {
public:
  Foo() {}
  virtual ~Foo() = 0;
  virtual int Bar() = 0;
};

class TestFoo : public Foo {
public:
  int Bar() { return 0; }
};

extern "C" {
  Foo* foo;
  void init() {
    // Runtime error: undefined symbol: _ZN3FooD2Ev
    foo = new TestFoo(); // causes error
  }
  void cleanup() { delete(foo); }
  void bar() { foo->Bar(); }
}

重点是将我的类的功能(这里只是最小的玩具类作为示例)暴露为一个简单的 C API,其中有三个函数 init, cleanup, 和 bar.

当我尝试加载共享库(使用 R 中的 dyn.load)时,我会收到一个错误:

unable to load shared library 'test.so':
test.so: undefined symbol: _ZN3FooD2Ev

看起来无法找到Foo构造函数。我做错了什么,如何修复?

更新: 谢谢,jbar! 所以是 Foo 析构函数。从错误信息中的神秘符号 _ZN3FooD2Ev 中可以知道吗?FooD 中的 D 代表析构函数吗?

3个回答

18
更新:原来是Foo析构函数。从错误消息中的神秘符号_ZN3FooD2Ev我能知道这个吗?FooD中的D代表析构函数吗?
您可以使用程序c++filt。
因此,c++filt _ZN3FooD2Ev 返回 "Foo :: ~ Foo()"。

1
哇,我希望我多年前就知道这个。谢谢! - Richard Żak

10
我们不能声明纯虚析构函数。即使将虚拟析构函数声明为纯虚函数,它也必须为析构函数实现一个空的函数体(至少)。

1
这样的函数体应该如何实现?如果我为基类实现它,g++ 会抱怨重定义。 - Christoph Wurm
请问您能否发布明确的代码解决方案?是 virtual ~Foo() {} 吗? - Buddhisthead

3
关于您的更新,"_ZN3FooD2Ev" 是 "Foo::~Foo()" 的名称修饰
请查看 "demangle" 程序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接