Search code examples
c++singletonshared-librariespoco-librariesdynamic-loading

Using static singleton class instance causes dynamic loading to fail


I am making a shared library which exports a function that uses a static class instance. The shared library is intended to be dynamically loaded. However, for some reason using the static class instance causes dynamic loading to fail. I am loading the library using Poco.

//my_library.h
#ifndef MY_LIB_H
#define MY_LIB_H

#define DUMMY_MSG 1;

class SendClass
{
  public:
    SendClass() = default;
    SendClass( const SendClass &other ) = delete;
    SendClass &operator=( const SendClass &other ) = delete;

    static SendClass *get_instance(){ return &singleton_instance; };

    int send(){ return DUMMY_MSG; };

  private:
    static SendClass singleton_instance;
};

extern "C" __attribute__ ((visibility ("default"))) int send();//this is the function to be exported

inline int send()
{
  return SendClass::get_instance()->send();
}

#endif // MY_LIB_H

I compile the above header file into a shared library using the command below, and put the library under /tmp/

g++ -shared -fPIC -o libexp.so my_library.h

And then I attempt to load the library in my main program

//main.cpp
#include "Poco/SharedLibrary.h"

using namespace std;

typedef int(*SENDFUNC)();

int main
(
  int argc,
  char **argv
)
{
    Poco::SharedLibrary lib;
    lib.load( "/tmp/libexp.so" );    //crashes here!
    SENDFUNC send_func = (SENDFUNC)lib.getSymbol("send");
    int msg = send_func();
    return 0;
}

The program crashes at the line "lib.load( "/tmp/libexp.so" );" with the following message:

terminate called after throwing an instance of
'Poco::LibraryLoadException' what(): Cannot load library

However, if I change the body of SendClass::get_instance to the following, the dynamic loading is completed successfully

//if SendClass::get_instance is implemented as follows, dynamic loading succeeds    
static SendClass *get_instance(){ return new SendClass; };

So why does using a static instance cause dynamic loading to fail?


Solution

  • As per @ALX23z's advice I solved the problem by adding the following cpp file

    //my_library.cpp
    #include "my_library.h"
    
    SendClass SendClass::singleton_instance;