1

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

1 に答える 1

2

dlopen(3)の man ページを注意深く何度か読んでください。

/ファイル パスに特定の処理が含まれていない場合に発生します。

dlopen 次のようなパスにする必要があります(そうしない と、環境変数の最後に./foo.so追加します が、これによりセキュリティ上のリスクが生じる可能性があるため、お勧めしません).LD_LIBRARY_PATH

(常に結果 と関数呼び出しのNULL 両方 に対してテストし 、失敗時に表示します)dlopendlsymdlerror()

ところで、プラグイン マネージャーは次のようにコンパイルする必要があります。

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

言及しないplugin_manager.o

于 2014-07-17T13:26:58.350 に答える