【发布时间】:2021-07-01 15:00:56
【问题描述】:
我正在尝试创建一个“游戏平台”,让用户可以选择要玩的游戏以及渲染它的图形库。这些游戏和图形库被实现为动态库,在运行时加载。我们将把游戏平台称为核心。 共享库包含在运行时使用 RTLD_LAZY 标志加载的类,但是如果我使用 RTLD_NOW 加载它,程序将正确编译。 我遵循this 教程以避免名称混淆,并且像这样使用共享库上定义的类。 目前,如果方法不调用核心类的任何方法(仅使用类的参数),它就可以正常工作。 (见下面的代码)
// Working code
void libNCurses::refreshScreen(Core *core)
{
if (core->input != Input::None)
mvaddch(0,0,'c');
else
mvaddch(0,0,' ');
refresh();
}
但是当我想调用 Core 类的某个方法时,程序崩溃并抱怨未定义的符号(使用的方法的符号)。 (见下面的代码)
// Not working code
void libNCurses::refreshScreen(Core *core)
{
std::vector<Object *> objs = core->getObjects();
for (auto obj = objs.begin(); obj != objs.end(); obj++)
mvaddch(10, 10, 'O');
if (core->input != Input::None)
mvaddch(0,0,'c');
else
mvaddch(0,0,' ');
refresh();
}
当然,Core 标头包含在共享库中。 任何人都可以向我解释为什么会发生这种情况以及如何解决它?
【问题讨论】:
-
您的结果描述需要更清楚,通常“程序崩溃”表示运行时错误,但未定义符号通常仅限于编译时。您能否澄清一下您何时收到错误,以及它实际上是由您的程序还是由构建工具产生的?
-
程序崩溃并抱怨未定义的符号,因为共享库在运行时加载了 RTLD_LAZY 标志。我已将其更改为在调用 dlopen(使用 RTLD_NOW)时加载所有符号,并且编译它没有问题。当调用 core->getObjects() 方法时,它继续抱怨。
-
显示插件和主程序的编译和链接命令(例如
g++和GCC 的选项)。提供一些minimal reproducible example。阅读Drepper's paper How to write shared libraries。并使用dlerror。或许可以在RefPerSys 的源代码中寻找灵感。你的操作系统是 Linux 的吗? -
当前使用 WSL2。编译通过makefile 完成。链接在 core class 内的运行时完成。 IGfxLibrary 和 IGLibrary 是 classes contained on the shared libs 的接口。我会检查 Drepper 的论文并检查 RefPerSys 源代码。
标签: c++ shared-libraries dlopen name-mangling