gpt4 book ai didi

c++ - 当 .so 尝试使用主可执行文件中的类时,dlopen() 给出未解析的符号错误。为什么?

转载 作者:搜寻专家 更新时间:2023-10-31 00:44:31 24 4
gpt4 key购买 nike

我在 Linux 上,问题是关于 C++ 类的共享对象。

当我的共享对象试图使用链接到主可执行文件的资源时,问题就来了。我有以下代码:

加载程序.cpp:

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

using namespace std;

int main(int argc, char** argv) {
for(int i=1; i<argc; ++i) {
string pth = "./";
pth.append(argv[i]);
void* dh = dlopen(pth.c_str(), RTLD_NOW);
if(dh==NULL) {
cerr << dlerror() << endl;
return 1;
}

CommonInfo::GetInfoFunc getInfo = (CommonInfo::GetInfoFunc)(dlsym(dh,"getInfo"));
if(getInfo==NULL) {
cerr << dlerror() << endl;
return 1;
}

CommonInfo* info = getInfo();
cout << "INFO: " << info->getX() << endl;
delete info;
}
return 0;
}

通用信息.h:

#include <string>

class CommonInfo {
public:
typedef CommonInfo* (*GetInfoFunc)();
private:
std::string x;
public:
CommonInfo(const std::string& nx);
std::string getX() const;
};

编辑:我不小心忘记了 ctrl-c + ctrl-v CommonInfo.cpp 的来源。当然,它在编译时就存在,所以 CommonInfo.cpp:

#include "CommonInfo.h"

CommonInfo::CommonInfo(const std::string& nx) : x(nx) {
}

std::string CommonInfo::getX() const {
return x;
}

Plugin.h 头文件:

#include "CommonInfo.h"
extern "C" CommonInfo* getInfo();

一个非常简单的 Plugin.cpp:

#include <iostream>
#include "Plugin.h"
#include "CommonInfo.h"

using namespace std;

CommonInfo* getInfo() {
return new CommonInfo("I'm a cat!");
}

编译完成:

g++ -rdynamic -ldl -Werror CommonInfo.cpp loader.cpp -o loader
g++ -shared -fPIC -Werror Plugin.cpp -o Plugin.so

运行:

./loader Plugin.so

然后出现错误:

./loader: symbol lookup error: ./Plugin.so: undefined symbol: _ZN10CommonInfoC1ERKSs

确实,使用 nm Plugin.so 查看 Plugin.so | grep -i CommonInfo 它为这个符号(未解析)给出了一个“U”,这完全没问题。此外,使用 nm loader.so | 查看加载程序的二进制文件 | grep -i CommonInfo 我可以找到带有“T”的符号,这也可以。问题是,dlfcn.h 不应该从主二进制文件中解析有问题的符号吗?没有这个功能,使用这些东西就变得非常困难……我是否必须为 CommonInfo 编写一个类工厂函数,从插件中使用 dlfcn 加载它并调用它?

提前致谢,丹尼斯

最佳答案

我没有仔细查看您的代码,但我过去发现了当我没有使用 -E 链接可执行文件时您在标题中描述的行为。 (或者 -Wl,-E 当链接到 gcc 而不是 ld 时。)

请注意,并非所有平台都允许共享库从调用二进制文件中获取符号。 Linux 和 *BSD 允许您这样做。但是如果你想移植到 Windows,你将无法使用这种模式。我相信还有一些 Unix 类型的操作系统不允许您这样做。 (已经有一段时间了,所以我不记得了……也许是 Solaris?)

关于c++ - 当 .so 尝试使用主可执行文件中的类时,dlopen() 给出未解析的符号错误。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8536880/

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