用dlsym加载so文件,无法加载库

时间:2014-07-17 13:20:15

标签: c++ plugins shared-libraries dlsym

我正在实现一个从.so文件加载插件的API。要加载它我使用dlsym()函数。为了检查它是否有效,我已经实现了一个测试插件(下面)并且为了简单起见我只加载“初始化”功能。要编译我的代码,我首先使用以下命令创建.so文件:

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

之后我按如下方式运行plugin_manager.cpp:

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

但是在运行a.out并输入正确的文件名后,我收到一条错误,我无法加载.so文件。有没有人知道如何解决这个问题?

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;
         }

1 个答案:

答案 0 :(得分:2)

仔细阅读 并多次阅读dlopen(3)手册页。

当flle路径不包含任何/时,会发生某些特定处理。

您应dlopen ./foo.so之类的路径(否则在.环境变量的末尾添加LD_LIBRARY_PATH,但这可能会带来安全风险,所以我不喜欢建议这样做)

(始终针对NULLdlopendlsym函数调用进行测试,并在失败时显示dlerror()

BTW,您的插件管理器应编译为:

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

不要提及plugin_manager.o