2

静的ライブラリとそれらを使用するプロジェクトごとに、何らかの方法でモジュール名を定義する必要があります。次のように単純にこれを行うことはできません:

std::string const module_name = "my module";

静的メンバーの初期化中にこの値が必要になるためです。静的データの初期化順序が定義されていないため、module_name変数を使用しようとしても初期化されていない可能性があります。

私が定義したこの問題を解決するには

inline std::string const& module_name() 
{
    static std::string const name = "my module";
    return name;
}

モジュールごとに。module_name()ただし、すべての呼び出しが親モジュールからの実装を使用するように解決されているため、これは機能しません(module_name()常に親実行可能プロジェクトの名前を返します)。そして、私はその理由を理解していません。このインライン関数は静的ライブラリで定義および使用されるため、実際のモジュール名を取得する必要があることを望みました。この関数がコンパイラによってインライン化されていないためですか?

この問題を解決するための推奨される方法はありますか?

コンパイラ: VC++10 および gcc、VC++10 でテスト済み

4

1 に答える 1

2

外部リンケージを持つエンティティは、プログラム内で1つの定義しか持てないため、1つのプログラムで同じ関数の複数の定義を持つことができないのは当然のことです。

インライン化とは関係ありません。リンカは同じシンボルの複数の定義を確認し(テンプレートのインスタンス化やインライン関数、および動的ライブラリを使用する場合は他のシンボルでよく発生します)、使用する定義を1つ選択します。

各ライブラリに個別の定義を持たせるには、内部リンケージが必要です。これは、関数を静的にするか、名前のない名前空間に配置するか、またはなどのプラットフォーム固有のメソッドを使用し__dllimport__attribute((visibility("hidden")))、シンボルがプライベートであることをコンパイラに通知することで実行できます。共有ライブラリにエクスポートする必要があります(したがって、同じシンボルの別の定義に置き換えられることはありません)。

または、各モジュールを独自の名前空間に配置し、関数をその名前空間に配置するだけで、各関数は異なり、干渉しなくなります。

于 2012-07-11T13:52:14.010 に答える