2017-06-27 43 views
1

質問を理解するために、ダイナミックライブラリをロードするプログラムについて詳しく説明します。それは半減期の専用サーバーです。実行可能ファイルの横にある古いlibstdC++を使用します。 問題を避けるために、新しい標準ライブラリの機能を使用するときは、通常、プロジェクトを統計的にlibstdC++にリンクします。libstdC++ダイナミックライブラリでの静的リンク

私の友人は、異なるコンパイラライブラリでコンパイルされた2つがロードされている場合や、サーバーから関数(古いlibstdC++の観点から実装されている)を呼び出すと、libstdC++静的リンクが問題を引き起こす可能性があると言いました。

本当ですか?この問題を解決するにはどうすればよいですか?

答えて

1

共有ライブラリが公開するAPIは、ホストアプリケーションが期待するのと同じABIを使用する必要があります。つまり、関連するタイプは同じレイアウト、サイズ、配置でなければなりません。

APIに公開されているタイプがstd::の場合、またはC++の例外がスローされる場合は、同じ標準ライブラリのヘッダーとマクロを使用して共有ライブラリをコンパイルする必要があります。この場合、ホストアプリケーションに付属のlibstdc++に動的にリンクすることができます。

APIに公開されているstd::タイプがなく、共有ライブラリから例外がスローされない場合は、静的にlibstdc++にリンクできます。しかし、すべての外部シンボルは共有ライブラリから引き続き公開されるため、RTLD_DEEPBINDフラグを持たないdlopenへの呼び出しがロードされると、ホストアプリケーションから同じ名前のシンボルが使用されますあなたが静的にリンクすることを望んでいたもので、あなたの友人がおそらく参照しているその未定義の動作を引き起こす可能性があります。これを避けるには、共有ライブラリのすべてのシンボルをローカルにし、APIシンボルのみをグローバルとして公開するためにリンカバージョンのスクリプトが必要です。

MYHALFLIFEPLUGIN_0.0 { 
    global: half_life_foo,half_life_bar; # Explicitly list symbols to be exported. 
    local: *; # Hide everything else. 
}; 

そして-Wl,--version-script=<filename>コンパイラリンカオプション(LDFLAGS)で、このスクリプトを使用するようにリンカに指示:ような何か。 -static-libstdc++オプションに加えて、-static-libgccリンカオプションが必要です。

はまた、より多くの詳細については、

一読を持っています。

+0

この回答を書いていただきありがとうございます。あなたは私には分かりませんでした。私はちょっと待って答えを受け入れます。 – Inline

+0

@Inline私は何かを見逃しているかもしれません。 'ldd'と' nm'はあなたの親友です:あなたの共有ライブラリが予期しない何かをリンクしていないことを確認してください。 –

0

はい、該当します。一番簡単な例は、ライブラリにnewというオブジェクトを作成し、同じSTLを使用しない別のライブラリにdeleteというオブジェクトを作成する場合です。非互換性がバイナリ(ライブラリ、EXE)の国境を越えていないことを確認してください

  • 使用ダイナミックリンクSTL
  • 用:

    あなたは2つのソリューションを持っています。これを行う難しい方法は、ライブラリにC API(C++なし)のみを公開させることです。
+1

この例は、MSVCの実行時に適用され、Linuxおよびg ++では適用されません。 –

+0

@ MaximEgorushkin Linuxおよびg ++に適用されます。これは実際にはC++プラットフォームとコンパイラに適用されます。Linuxでは、STLをシステムにインストールして、すべてのバイナリをコンパイルするので、一般的には簡単です。しかし、まだlibstdC++とlibC++を混在させることはできません。互換性のない2つのバージョンのlibC++を混在させることもできません。 –

+0

STLはペダンティックであるため、C++標準ライブラリの一部であり、 'new' /' delete'はSTLからのものではありません。 –

関連する問題