私が作成した静的ライブラリを使用するアプリケーションがあります。ライブラリ内の 1 つの .cpp ファイルには静的変数宣言があり、その ctor は何かを行うシングルトンの関数を呼び出します。たとえば、文字列を追加します。
アプリケーションからそのライブラリを使用すると、シングルトンには、追加されるはずだった文字列の痕跡が含まれていないようです。
私は間違いなく何かを見逃していますが、何がわかりません..
私が作成した静的ライブラリを使用するアプリケーションがあります。ライブラリ内の 1 つの .cpp ファイルには静的変数宣言があり、その ctor は何かを行うシングルトンの関数を呼び出します。たとえば、文字列を追加します。
アプリケーションからそのライブラリを使用すると、シングルトンには、追加されるはずだった文字列の痕跡が含まれていないようです。
私は間違いなく何かを見逃していますが、何がわかりません..
アプリケーションで明示的に使用されていないオブジェクトが静的ライブラリにある場合。次に、リンカーはそのオブジェクトを lib からアプリケーションにプルしません。
静的ライブラリと動的ライブラリには大きな違いがあります。
ダイナミック ライブラリ:
コンパイル時に、ダイナミック ライブラリからは何も取得されません。実行時にシンボルを明示的にロードして解決するために、追加のコードが追加されます。実行時にライブラリ全体がロードされるため、オブジェクト初期化子が呼び出されます (ただし、実装の詳細はいつですか)。
静的ライブラリは非常に異なる方法で処理
されます。静的ライブラリに対してリンクすると、ライブラリで定義されているアプリケーションで定義されていないすべてのアイテムがアプリケーションに取り込まれます。これは、ライブラリが解決できる依存関係がなくなるまで繰り返されます。これの副作用は、明示的に使用されていないオブジェクト/関数がライブラリから取り出されないことです (したがって、直接アクセスされないグローバル変数は取り出されません)。
これについての私の記憶は少し曖昧ですが、初期化順序の問題に見舞われている可能性があります。異なるファイルの静的変数初期化子が呼び出される順序は保証されていないため、ライブラリ内の静的変数が初期化されているときにシングルトンがまだ初期化されていない場合、表示されている効果が生じる可能性があります。
私がこれらの問題を回避した方法は、このようなことを行い、または何かinit
の開始時に呼び出す何らかの明示的な関数を用意することです。main
オブジェクトファイルとライブラリの引数をコンパイラ(または実際にはリンカー)に与える順序をいじることができるかもしれませんが、それも私にとってはうまくいったからです。特定のリンカーだけでなく、おそらく特定のバージョンも。
静的初期化を行うクラスをリファクタリングして、他のそのようなクラスに依存しないようにします。つまり、各クラスの初期化を独立して自己完結型にします。