【发布时间】:2011-12-16 16:10:04
【问题描述】:
我在 Linux 上,问题是关于 C++ 类的共享对象。
当我的共享对象尝试使用链接到主可执行文件的资源时,问题就出现了。我有以下代码:
loader.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;
}
CommonInfo.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 | grep -i CommonInfo 查看 Plugin.so 会为这个符号提供一个“U”(未解决),这完全没问题。
此外,使用nm loader.so | grep -i CommonInfo 查看加载程序的二进制文件,我可以找到带有“T”的符号,这也可以。
问题是,不应该 dlfcn.h 从主二进制文件中解开有问题的符号吗?没有这个功能,使用这些东西就变得非常困难......我是否必须为 CommonInfo 编写一个类工厂函数,使用插件中的 dlfcn 加载它并调用它?
提前致谢, 丹尼斯
【问题讨论】:
-
(更正:不是 C++ 类的共享对象,虽然在我开始写这篇文章的时候,Plugin.so 中有一个类,但为了让错误更清楚,我把它去掉了。)
-
看来是CommonInfo的构造函数的问题。这是在哪里定义的?
-
哎呀,它就在那里,我只是忘了写在这里。 :)
-
仅供参考:
$ echo _ZN10CommonInfoC1ERKSs | c++filt产生CommonInfo::CommonInfo(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) -
我很确定你在可执行编译行也需要
-fPIC。
标签: c++ plugins shared-libraries