简体   繁体   English

从 C 可执行文件加载 C++ 动态库时收到错误“未定义符号”

[英]Receiving the error “undefined symbol” when loading C++ dynamic library from C executable

I am trying to write a plugin for a popular program whose code and compilation process I do not have control over.我正在尝试为一个我无法控制其代码和编译过程的流行程序编写一个插件。 The program is written in C.程序用 C 编写。 However, I have written parts of my plugin in C++, since I use the QT5 library for graphics capabilities.但是,我在 C++ 中编写了部分插件,因为我使用 QT5 库来提供图形功能。 The functions that the C program calls are written in C. C程序调用的函数写在C中。

When the C program tries to load the plugin (shared library), it produces this error:当 C 程序尝试加载插件(共享库)时,会产生以下错误:

dlopen('build/libfoo.so') failed: build/libfoo.so: undefined symbol: _ZTV13JoystickPanel

JoystickPanel is a class in the C++ part of the program. JoystickPanel是程序 C++ 部分中的 class。

I've tried rewriting parts of the program in C, but the error was unaffected.我尝试在 C 中重写部分程序,但错误不受影响。 I know that I could rewrite the entire program in C, but I'd rather not have to switch to another, more C-friendly GUI framework.我知道我可以在 C 中重写整个程序,但我宁愿不必切换到另一个对 C 更友好的 GUI 框架。 I've also opened up libfoo.so in a text editor and search for JoystickPanel , but it appears to be mangled as _ZN13JoystickPanel .我还在文本编辑器中打开了libfoo.so并搜索JoystickPanel ,但它似乎被损坏为_ZN13JoystickPanel

Are there any compiler options or solutions that I'm missing?我缺少任何编译器选项或解决方案吗?

I have no idea what _ZN13JoystickPanel means, since it's not apparently a valid mangled C++ name.我不知道_ZN13JoystickPanel是什么意思,因为它显然不是一个有效的损坏的 C++ 名称。 It should perhaps be _ZN13JoystickPanelE , which would translate to JoystickPanel .它可能应该是_ZN13JoystickPanelE ,它将转换为JoystickPanel That'd be symbol name for sure, but without much meaning anyway.那肯定是符号名称,但无论如何都没有多大意义。 You must have truncated something: I tried quite a bit and just can't generate an object file that would include _ZN13JoystickPanel as the complete symbol.您一定截断了一些东西:我尝试了很多,但无法生成包含_ZN13JoystickPanel作为完整符号的 object 文件。 It's just a prefix, there should be a "second half" attached to it - was there?它只是一个前缀,应该附加一个“后半部分”——有吗?

But _ZTV13JoystickPanel is the vtable for the JoystickPanel class.但是_ZTV13JoystickPanelJoystickPanel class 的 vtable。 It's missing because you didn't provide implementations for all the virtual methods of the JoystickPanel class.它丢失是因为您没有为JoystickPanel class 的所有虚拟方法提供实现。 Most likely, you didn't invoke moc properly, or forgot to compile and link its output.很可能,您没有正确调用 moc,或者忘记编译和链接它的 output。

You need to show a complete build script for your plugin at the very least (the .pro file, or CMakeLists.txt ).您至少需要为您的插件显示一个完整的构建脚本( .pro文件或CMakeLists.txt )。 You'll also need to provide a github link to your project (I presume it's open source).您还需要为您的项目提供 github 链接(我认为它是开源的)。

The symbols you want to find in the compiled output are at least _ZTV13JoystickPanelD#Ev - virtual destructors, where # is a digit, _ZTV13JoystickPanel - the virtual method table,您想在编译后的 output 中找到的符号至少是_ZTV13JoystickPanelD#Ev - 虚拟析构函数,其中 # 是数字, _ZTV13JoystickPanel - 虚拟方法表,

Those symbols may be absent when compiled with optimization and/or LTCG, but also absent will be references to them.当使用优化和/或 LTCG 编译时,这些符号可能不存在,但也会不存在对它们的引用。

You may wish to delete the build folder and rebuild your project, just to be sure.您可能希望删除 build 文件夹并重新构建您的项目,以确保这一点。 qmake is bad at dependency generation for the makefiles it produces, so if you use it, I suggest switching to cmake + ninja . qmake不擅长为它生成的 makefile 生成依赖项,所以如果你使用它,我建议切换到cmake + ninja

Apparently, I'd forgetten to put the #include "moc_controller.cpp" line at the bottom of a file that needed it.显然,我忘记将#include "moc_controller.cpp"行放在需要它的文件的底部。

For anyone else chasing this issue while using Qt on CMake, consider making sure that the proper lines are added.对于在 CMake 上使用 Qt 时遇到此问题的其他人,请考虑确保添加了正确的行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM