1

ロードしている C 共有オブジェクトがありますdlopen。C 共有オブジェクトには、別のライブラリが静的アーカイブ (完全に指定されたパス/usr/local/.../libsomelib.a) として含まれています。libsomelib.aは C++ ライブラリであり、グローバルおよび静的ローカルがあります。

RTLD_GLOBALUbuntu では、共有ライブラリをおよびで開いたときに、静的イニシャライザが実行されていないように見えますRTLD_GLOBAL | RTLD_LAZY。私が見ている症状は、プログラムのクラッシュです。

私が見ている動作は、-nostartfilesorとのリンクに似ているよう-nostdlibです (ただし、私はそれらを使用していません)。C++ Static Constructors と dlopen'd Shared Librariesで同様のスレッドを見つけましたが、これは NetBSD システム用です。

EXE が明示的にlibsomelib.a関数をインクルードして呼び出した場合、C++ ライブラリが初期化され、関数ポインターを介して呼び出すときにプログラムがクラッシュしなくなりました。

編集: 共有オブジェクトを構築する方法は次のとおりです (C と C++ を混合/一致させることなく、私が経験した最も単純なケースです)。cryptopp-so-test.exeコールdlopen:

CXXFLAGS = -g -ggdb -fPIC -DDEBUG -O1 -Wall -Wextra -Wno-unused -DUSE_PRECOMPILED_HEADERS=1 -I. -I/usr/local/include/cryptopp
...
precompile:
    $(CXX) $(CXXFLAGS) pch.h -o pch.h.gch

cryptopp-so-test.exe: precompile $(EXEOBJECTS)
    $(CXX) $(CXXFLAGS) -o $@ $(EXESOURCES) -ldl -lpthread

dsotest: precompile $(DLLOBJECTS)
    $(CXX) $(CXXFLAGS) $(DLLSOURCES) -o dsotest-1.so -shared /usr/local/lib/libcryptopp.a

上記のコードは 1 つの EXE (cryptopp-so-test.exe) と 1 つの SO (dsotest-1.so) をビルドしますが、実際には 4 つの共有オブジェクトをビルドしてロードします (これらは同じようにビルドされます)。

C++ コンポーネントを含む C 共有オブジェクトが実行されたときに、静的初期化子が確実に実行されるようにするには、どのフラグ (またはその他のメソッド) を使用する必要がありますdlopenか?

4

1 に答える 1