2016-12-07 4 views
0

多くのC++テンプレート関数を参照するために作成した共有ライブラリがあります。これらのシンボルは、共有ライブラリのエクスポートテーブルに弱い参照として入力されます(たとえば、nmを使用して共有ライブラリのシンボルを表示すると、タイプWと表示されます)。これは、実行時に、これらのシンボルが、最初にロードされた別の共有ライブラリからのコピーによって挿入される可能性があることを意味します。どのように共有ライブラリのシンボルを強くすることができますか?

私の共有ライブラリは、他のライブラリからではなく、ライブラリ自体に含まれるこれらの関数のコピーを使用することが重要です。これを確実にする方法はありますか?さまざまなテンプレートのインスタンシエーションのすべてを静的に共有ライブラリにリンクするのと同じように私には聞こえます。

答えて

1

これは実行時に、最初にロードされた別の共有ライブラリのコピーによって、これらのシンボルが挿入される可能性があることを意味します( )。彼らは関係なく、弱い属性を介在させることができる

注(LD_DYNAMIC_WEAKは通常されていない、設定されていない限り、動的リンカー扱いは、strongsと同様weaksと言うthis GCC postを参照します)。

それは私の共有ライブラリ がない他のライブラリから、ライブラリ自体内 を含まれているこれらの関数のコピーを使用して自分のアプリケーションのために重要です。 これを保証する方法はありますか?

あなたができることはいくつかあります。

普通は、fvisibility=hiddenをCFLAGSに追加して、ライブラリからシンボルをエクスポートしないようにし、エクスポートされた機能を__attribute__((visibility("default")))でマークすることをお勧めします。これにより、コンパイル時の最適化が向上し、rtldがより少ないシンボルを処理する必要があるため、より高速な起動が可能になります。

限定された形の-fvisility=hiddenである-fvisibility-inlines-hiddenを使用することは、貧しい人の限られた解決策です。インライン関数(STLテンプレートの結果など)のみを非表示にします。

ソースコードを混乱させたくない場合は、-Wl,-Bsymbolicとリンクしてください。可能であれば、参照がライブラリ内で強制的に解決されます。

- EDIT -

実際にあなたが動的にエクスポートされた関数に、イントラライブラリ参照を挟んから他のライブラリ(またはそれ自体を実行可能ファイルを)防ぐために-fvisibility=hiddenを有効にしても-Bsymbolicが必要になります。

+0

ありがとうございました。 '-Bsymbolic'や' -Bsymbolic-functions'は私の問題の解決策です。私はおそらく、公開APIを厳密に定義し、 '-fvisibility = hidden'を使用することを推奨するアプローチをとると思います。それはベストプラクティスのようです。 –

+0

2番目の考えでは、 '-fvisibility = hidden'でも' -Bsymbolic'が必要だと思います。エクスポートされていなければ、他の共有ライブラリに関数を挿入できます。また、 'fvisibility = hidden'を使いこなすのを避けるため、' -fvisiblity-inlines-hidden'というより単純な変種を使うことができます。これは、全てのインライン関数(STLテンプレートを含む)を隠すでしょう。私は答えを更新しました。 – yugr

関連する問題