3

私のシナリオでは、実行時にロードされる共有オブジェクトであるプラグインが「ホストアプリケーション」からシンボルにアクセスして、アプリケーションに任意の機能を追加できるようにします。

私はこれを試みましたが、これを行う方法を見つけられず、これが可能かどうかについての手がかりがありません。それで、私はこれをどうにかして行うことができますか、それともプラグインを使用するアプリケーションが使用する代替手段はありますか?

私はFedora15、Linux2.6.4を使用しています。ただし、ソリューションがクロスプラットフォームになることを願っています。

4

1 に答える 1

3

3つの主要なアプローチがあります。

  1. 関数ポインタの構造をアプリケーションからDLLに渡し、共有したいシンボルにアクセスできるようにします。これは最も移植性の高い方法ですが、すべての関数ポインターを作成するのはちょっと面倒です。何かのようなもの:

    // In shared header
    struct app_vtable {
      void (*appFoo)();
    };
    
    // In plugin:
    const app_vtable *vt;
    void set_vtable(const app_vtable *vt_) {
      vt = vt_;
    }
    
    void bar() {
      vt->appFoo();
    }
    
    // In application:
    void foo();
    const app_vtable vt = { foo };
    
    void loadplugin() {
      void *plugin = dlopen("plugin.so", RTLD_LAZY);
      void (*pset_vtable)(const app_vtable *) = dlsym(plugin, "set_vtable");
    
      pset_vtable(&vt);
    
      void (*pbar)() = dlsym(plugin, "bar");
      pbar();
    }
    
  2. アプリケーションをライブラリに移動し、実行可能ファイルをこのライブラリにリンクして、その中のエントリポイントを呼び出すだけです。そうすれば、プラグインは同じライブラリをリンクして、そのシンボルに簡単にアクセスできます。これも非常に移植性がありますが、メインアプリライブラリで位置に依存しないコードを使用する必要があるため、パフォーマンスが低下する可能性があります(ただし、この場合、アーキテクチャによっては固定マッピングを使用できない場合があります)。 。

  3. Linuxのみ(および可能な他のELFプラットフォーム)では-rdynamic、アプリケーション実行可能ファイルからシンボルを直接エクスポートするために使用できます。ただし、これは他のプラットフォームへの移植性はあまり高くありません。特に、これらはWindowsのこれと同等ではありません。
于 2011-10-09T22:26:53.610 に答える