8

テンプレートのみのC++ライブラリを作成しています。ただし、「空の」共有ライブラリも提供したいので、SONAMEを制御することで、テンプレートが変更されてインスタンス化されたテンプレートABIの非互換性が発生するたびに、テンプレートコンシューマーの再構築を強制できます。

悲しいことに、特定のユーザーが-Wl,--as-needed彼の中にいる場合、コンパイルされた実行可能ファイルがそこからシンボルを要求していないためLDFLAGS、リンカーは私の共有ライブラリを削除しようとしています。NEEDEDプログラムが常にライブラリに対してリンクされるようにするにはどうすればよいですか。できれば、不要なダミー関数呼び出しを導入しないようにします(または、必要な場合は、それらの負担を最小限に抑えます)。

編集:注として、特定のテンプレートクラスは静的メソッドを提供し、通常はそれらの静的メソッドのみが使用されます。したがって、コンストラクターに入れられたものに依存することはお勧めできません。私は、すべてのメソッドに何らかの強制を課すことを避けたいと考えています。


@EmployedRussianに触発されて、私は達成しました:

extern int dummy;

namespace
{
    struct G
    {
        inline G()
        {
            dummy = 0;
        }
    };

    static const G g;
}

しかし悲しいことに、それはヘッダーファイルを含むすべてのユニットに対して1回割り当てを実行します。

4

2 に答える 2

4

ただし、「空の」共有ライブラリも提供したいので、SONAMEを制御することで、テンプレートが変更されてインスタンス化されたテンプレートABIの非互換性が発生するたびに、テンプレートコンシューマーの再構築を強制できます。

これにより、実行時にエラーが発生します。

を使用しなくても、同じ結果(実行時エラー)を簡単に達成できますSONAME。テンプレートヘッダーの1つに、runimeで実行されるグローバルオブジェクトを配置します

  1. のアドレスを取るか、電話libmysolib_version_<N>する、または
  2. dlopen(libmysolib.so, ...)してくださいdlsym("libmysolib_version_<N>", ...)

Nその後、ABIを壊すたびにインクリメントし続けます。

できれば不要なダミー関数呼び出しを導入しない

アドレスを取ることlibmysolib_version_<N>は関数を呼び出しません。ランタイムリンカにそのシンボルを1回(起動時に)検出させるだけです。ただし、リンカーのガベージコレクションに反する可能性があります。

于 2012-08-12T18:02:39.657 に答える
2

別のアプローチをお勧めします:

myheader.h 

namespace mylib_1 {
   void foo(); 
   //all the code goes there
}
namespace mylib = mylib_1;

ユーザーからの呼び出し:

mylib::foo()

異なるmyheaderバージョンを使用するコードは、関数のシグネチャを変更するため、リンクされません。

このアプローチはICUで使用されます

于 2012-08-25T05:57:07.777 に答える