dlopen() を使用して共有ライブラリを別の共有ライブラリにロードしようとすると、問題が発生します。dlopen() を正しく使用する方法に関するすべてのチュートリアルを確認しました。したがって、簡略化されたコードは次のとおりです。
メイン共有ライブラリには、サブ共有ライブラリ (別名プラグイン) が実装する必要がある純粋仮想関数を持つクラスが含まれています。さらに、デフォルトの動作で実装されている他の機能がいくつかあります。クラスをロードして作成するシンボルを持つために、すべてのプラグインに追加されるマクロを作成しました。
主な共有ライブラリ
plugin.h:
Class A {
public:
virtual int func1() = 0;
virtual bool func2() const;
}
#define CREATE_CLASS(cls) extern "C" void *CreateClass(void) { return new cls; }
プラグイン.cpp:
bool A::func2() const { return true; }
main.so をビルドしてリンクする
g++ -g -Wall -Woverloaded-virtual -Wno-parentheses -O2 -fPIC -c -o plugin.o plugin.cpp
g++ -g -Wall -Woverloaded-virtual -Wno-parentheses -O2 -fPIC -rdynamic -shared plugin.o -ldl -o main-plugin.so
サブ共有ライブラリは、純粋仮想関数のみを実装します。他の関数はオプションですが、オーバーライドできます。
サブ共有ライブラリ
plugin-impl.cpp
Class B : public A {
public:
virtual int func1() { return 0; }
}
CREATE_CLASS(B)
これらは、サブ共有ライブラリを構築およびリンクするための行です。
sub.so をビルドしてリンクする
g++ -g -O3 -Wall -Werror=overloaded-virtual -Wno-parentheses -fPIC -c -o subPlugin.o subPlugin.cpp
g++ -g -O3 -Wall -Werror=overloaded-virtual -Wno-parentheses -fPIC -shared subPlugin.o -o subPlugin.so
これは、サブ共有ライブラリを開くための行です。LAZY、NOW、NOW | を試してみました。GLOBAL など、影響はありません。
メイン共有ライブラリのどこかで dlopen() を呼び出します。
handle = dlopen(file.c_str(), RTLD_LAZY);
これのほとんどは非常にうまく機能しています。ただし、サブ共有ライブラリをメイン共有ライブラリにロードしようとすると、dlopen は の未定義シンボルについて不平を言いbool A::func2() const
ます。関数はメインの共有ライブラリにしか存在しないため、とにかくエクスポートする必要があると思います。私を助けてください!私は非常に混乱しています!
解決
実行可能ファイルを変更できないため、次のオプションを g++ に追加して、メイン共有ライブラリをサブ共有ライブラリとリンクする必要があります。
-L$(PLUGINDIR) -Wl,-R$(PLUGINDIR) -lmain-shared
このセットでは、 を設定する必要はありませんLD_LIBRARY_PATH
。