gpt4 book ai didi

c++ - 带有动态加载库的 undefined symbol "typeinfo"

转载 作者:可可西里 更新时间:2023-11-01 18:39:15 26 4
gpt4 key购买 nike

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

基础.h:

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

基础.cpp:

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

主要.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

但是在运行时它会因为缺少类型信息符号而崩溃

liblib.so: undefined symbol: _ZTI4base

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

$ nm app | grep _ZTI4base
0000000000601050 V _ZTI4base

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

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

最佳答案

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

关于c++ - 带有动态加载库的 undefined symbol "typeinfo",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11730465/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com