I am trying to create a shared library using gcc 4.6 for Linux that loads dynamically. As described in many articles on the Internet, as well as in previous questions, I provide c-style factory methods in the library for creating and destroying objects. The code - in minimal form - looks like this:
base.h:
class base { public: base(); virtual ~base(); virtual int value() = 0; };
base.cpp:
#include "base.h" base::base() {} base::~base() {}
main.cpp:
#include "base.h" #include <dlfcn.h> #include <iostream> int main() { void* handle = dlopen("liblib.so", RTLD_NOW); if(handle == NULL) std::cout << dlerror() << std::endl; // dlsym, ... }
lib.cpp:
class derived : public base { public: derived() {} virtual ~derived() {} virtual int value() { return 42; } }; extern "C" derived* create_object() { return new derived(); }
Compiled with:
g++ -shared -fPIC lib.cpp -o liblib.so g++ base.cpp main.cpp -ldl -o app
At run time, however, it crashes due to a missing character such as info
liblib.so: undefined symbol: _ZTI4base
In previous questions I found here, this error was usually explained either by the absence of "= 0;" or missing virtual function definition. However, in the above example, base :: value is purely virtual, and the destructor has a definition. Oddly enough, nm tells _ZTI4base as defined in the application:
$ nm app | grep _ZTI4base 0000000000601050 V _ZTI4base
So why not the linker using this definition?
The only way I found to get the code to work is to implement the constructor and destructor in the header file. However, after that, the corresponding characters for the database are reported to liblib.so by nm and completely disappear from the application, which probably means that their definitions were compiled into a library, and not into the application, which I did not want to achieve. Does anyone have an idea how to make the above work without doing this?