1

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. However, I have written parts of my plugin in C++, since I use the QT5 library for graphics capabilities. The functions that the C program calls are written in C.

When the C program tries to load the plugin (shared library), it produces this error:

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

JoystickPanel is a class in the C++ part of the program.

I've tried rewriting parts of the program in C, but the error was unaffected. 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. I've also opened up libfoo.so in a text editor and search for JoystickPanel, but it appears to be mangled as _ZN13JoystickPanel.

Are there any compiler options or solutions that I'm missing?

notagull
  • 113
  • 1
  • 1
  • 11

2 Answers2

4

I have no idea what _ZN13JoystickPanel means, since it's not apparently a valid mangled C++ name. It should perhaps be _ZN13JoystickPanelE, which would translate to 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. 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. It's missing because you didn't provide implementations for all the virtual methods of the JoystickPanel class. Most likely, you didn't invoke moc properly, or forgot to compile and link its output.

You need to show a complete build script for your plugin at the very least (the .pro file, or CMakeLists.txt). You'll also need to provide a github link to your project (I presume it's open source).

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,

Those symbols may be absent when compiled with optimization and/or LTCG, but also absent will be references to them.

You may wish to delete the build folder and rebuild your project, just to be sure. qmake is bad at dependency generation for the makefiles it produces, so if you use it, I suggest switching to cmake + ninja.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • Thank you for your quick response. [Here is my `CMakeLists.txt` file](https://github.com/not-a-seagull/tasinput2/blob/cplusplus/CMakeLists.txt) (also links to the repository). To add on: when I open the `tasinput2_autogen/mocs_compilation.cpp` file, it says that no MOC files were found. I do have `Q_OBJECT` inside of my QWidget inheritors. – notagull Jun 02 '20 at 19:04
  • 1
    Do not use globbed sources. Like, ever. Just don't. They seem to work. And then they don't work. Just don't. If you have a library project, just add all the sources and headers manually to it. I mean it. I refuse to look into it any further until that is fixed ;) – Kuba hasn't forgotten Monica Jun 02 '20 at 19:22
  • 1
    @JohnNunley Also: what is the architecture and OS you're compiling this for? And the exact source of Qt you're using (e.g. a Linux distro package - include version too, or a Qt installer download, etc - be specific, imagine that I'll be following your steps exactly, because, well, I will). – Kuba hasn't forgotten Monica Jun 02 '20 at 19:24
  • I've removed the globs. I'm using Ubuntu 18.04.4 LTS. The version of the `qt5-default` package is `5.9.5+dfsg-0ubuntu2.5`. [Here is a list of every package I have with `qt` in the name](https://gist.github.com/not-a-seagull/19c12f66fe547bf2080d46ec06430c57). Thank you for all of your help. – notagull Jun 02 '20 at 19:34
  • Also, the program I'm making this for is `mupen64plus`. – notagull Jun 02 '20 at 19:54
  • 1
    Cool. I’ll see what I can figure out. – Kuba hasn't forgotten Monica Jun 02 '20 at 23:53
  • I was tinkering with the code a bit and looking into the MOC. Apparently, I forgot to add `#include "mocs_controller.cpp"` to the end of the `controller.cpp` file. That seems to have fixed the issue. Should I answer my own question with that solution? – notagull Jun 03 '20 at 00:24
  • 1
    Yes! Please answer it yourself! – Kuba hasn't forgotten Monica Jun 03 '20 at 02:35
0

Apparently, I'd forgetten to put the #include "moc_controller.cpp" line at the bottom of a file that needed it.

For anyone else chasing this issue while using Qt on CMake, consider making sure that the proper lines are added.

notagull
  • 113
  • 1
  • 1
  • 11