bl618515
bl618515

Reputation: 107

Loading so files with dlsym, cannot load library

I am implementing an API which loads plug-ins from .so files. To load them I am using the dlsym() function. To check if it works I have implemented a test plug-in (below) and to make things easier I am loading only the "initialize" function. To compile my code I am firstly creating the .so file with the following command:

      g++ -Wall -shared -rdynamic -fPIC plugin_test.cpp -o plugin_test.so

After that I run the plugin_manager.cpp as follows:

      g++ plugin_manager.cpp -o -plugin_manager.o -ldl

But after running the a.out and typing the correct filename, I get an error that I cannot load the .so file. Does anyone have a clue about how to solve this issue?

plugin_manager.cpp

      #include <dlfcn.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <string>
      #include <iostream>
      #include "plugin_interface.h"
      using namespace std;
      //typedef void (*test_function)(void);

      int main(void) {
       const char *error;
       void *module;
       //test_function initialize_test;
       //void (*initialize_test) (void);
       //test_function analyze_test;
       //test_function finalize_test;
       //load the DL library
       string filename;
       cout << "File :: " << endl;
       cin >> filename;
       module = dlopen(filename.c_str(), RTLD_LAZY);
       if (!module) {
           fprintf(stderr, "ERROR! Couldn't load library: %s\n",
           dlerror());
           exit(1);
       }

        //get and check symbol
        dlerror();
        initialize_f* initialize_function = (initialize_f*) dlsym(module, "initialize");
        if ((error = dlerror())) {
        fprintf(stderr, "ERROR %s\n", error);
        exit(1);
        }

        //create instance of the class
        PluginInterface* plugin = initialize_function();

        //use the class
        plugin->initialize();
        //call "initialize" function from the test plug-in
        //(*initialize_test)();

        dlclose(module); //close the DL library
        return 0;
        }

plugin_interface.h

    #ifndef PLUGIN_INTERFACE_H_INCLUDED
    #define PLUGIN_INTERFACE_H_INCLUDED

    class PluginInterface{

    public:
        virtual void initialize() = 0;
        virtual void analyze() = 0;
        virtual void finalize() = 0;
    };

    //Definition of the pointer
    typedef PluginInterface* initialize_f();
    #endif // PLUGIN_INTERFACE_H_INCLUDED

test_plugin.cpp

         #include <iostream>
         #include "plugin_interface.h"
         using namespace std;

         class bbb :public PluginInterface {
           public:

         virtual void initialize(){
         cout << "Initialization";
         }

         void analyze(){
         cout << "Analysis";
         } 
         void finalize(){
         cout << "Finalization";
         }

         };

         //The functions we load must be qualified as extern "C" to avoid the symbol name being mangled
         extern "C" PluginInterface* initialize(){
         return new bbb();
         }
         int main()
         {


         //bbb* a = maker();
         //a->initialize();
         //Creating an instance and calling the "initialize" function with in
         PluginInterface* p = initialize();
         p->initialize(); 


         return 0;
         }

Upvotes: 1

Views: 1959

Answers (1)

Read carefully and several times the dlopen(3) man page.

When the flle path does not contain any / some specific processing happens.

You should dlopen a path like ./foo.so (otherwise add . at the end of your LD_LIBRARY_PATH environment variable, but this might open a security risk, so I don't advise doing that)

(always test against NULL result both dlopen and dlsym function calls and display dlerror() on failure)

BTW, your plugin manager should be compiled with:

      g++ -Wall -g plugin_manager.cpp -o -plugin_manager -ldl

Don't mention plugin_manager.o

Upvotes: 2

Related Questions