动态加载库的未定义符号“typeinfo”

Posted

技术标签:

【中文标题】动态加载库的未定义符号“typeinfo”【英文标题】:Undefined symbol "typeinfo" with dynamically loaded library 【发布时间】:2012-07-30 22:14:02 【问题描述】:

我正在尝试在 Linux 上使用 gcc 4.6 构建一个共享库,该库是动态加载的。正如网络上的许多文章以及之前的问题中所描述的,我在库中提供了 c 风格的工厂方法来创建和销毁对象。代码(最小形式)如下所示:

base.h:

class base 
public:
  base();
  virtual ~base();
  virtual int value() = 0;
;

base.cpp:

#include "base.h"
base::base() 
base::~base() 

main.cpp:

#include "base.h"
#include <dlfcn.h>
#include <iostream>

int main() 
  void* handle = dlopen("liblib.so", RTLD_NOW);
  if(handle == NULL) std::cout << dlerror() << std::endl;

  // dlsym, ...

lib.cpp:

class derived : public base 
public:
  derived() 
  virtual ~derived() 
  virtual int value()  return 42; 
;

extern "C" derived* create_object() 
  return new derived();

它编译得很好:

g++ -shared -fPIC lib.cpp -o liblib.so
g++ base.cpp main.cpp -ldl -o app

但是在运行时它会因为缺少 typeinfo 符号而崩溃

liblib.so: undefined symbol: _ZTI4base

在我在这里找到的以前的问题中,此错误通常是由于缺少一些“= 0;”或缺少虚函数的定义。然而,在上面的例子中,base::value 是纯虚函数,析构函数有一个定义。奇怪的是,nm 报告了应用程序中定义的 _ZTI4base:

$ nm app | grep _ZTI4base
0000000000601050 V _ZTI4base

那么为什么链接器不使用这个定义呢?

到目前为止,我发现让代码正常工作的唯一方法是在头文件中实现构造函数和析构函数。然而,在这样做之后,base 的相应符号在 liblib.so 中由 nm 报告,并且完全从 app 中消失,这可能意味着它们的定义被编译到库中而不是 app 中,这不是我想要实现的。有没有人知道如何在不这样做的情况下使上述工作?

【问题讨论】:

--demangle 传递给nm 以查看函数的解构名称。 【参考方案1】:

链接程序时需要-rdynamic 选项,以导出其符号并使它们可用于加载dlopen() 的库。

【讨论】:

以上是关于动态加载库的未定义符号“typeinfo”的主要内容,如果未能解决你的问题,请参考以下文章

建筑的未定义符号..在动态框架中

c语言动态库的加载问题!!!!请高手指点!!!!!!!!

使用 dlopen 加载动态库时抛出未定义的符号

Linux下C/C++动态库在运行时是怎样加载进来的

LD_PRELOAD加载动态库

LD_PRELOAD加载动态库