2012-04-09 4 views
7

私はと協力し、ここで説明する1つに基づいて、自己登録、抽象的な工場をテストしてきた:すべての私のテストケースで、抽象工場

https://stackoverflow.com/a/582456

、それは動作します魅力のように、私が望む機能と再利用を提供します。

私のプロジェクトでこの工場でリンクしているのは、cmakeを使っているのですが(それはarの問題のほうが多いようですが)。

リンクされた例には、同じbase.hpp、derivedb.hpp/cpp、および同等のderiveda.hpp/cppがあります。主に、私は単にファクトリをインスタンス化し、createInstance()を「DerivedA」と「DerivedB」でそれぞれ2回呼び出します。

ラインによって作成された実行ファイル:予想通り

g++ -o testFactory main.cpp derivedb.o deriveda.o 

作品。 (cmakeのを使用して、私は同様にArのみでこれをテストしている)ライブラリーに私の派生クラスを移動して、リンクすると失敗します。

ar cr libbase.a deriveda.o derivedb.o 
g++ -o testFactory libbase.a main.cpp 

は(derivedA.cppから)最初の静的インスタンス化とは決して秒を呼び出しますARラインに2を交換するderiveda.cppのインスタンスのみderivedb.cpp静的インスタンス化を呼び出し、いないことを静的インスタンス化、すなわち

// deriveda.cpp (if listed first in the "ar" line, this gets called) 
DerivedRegister<DerivedA> DerivedA::reg("DerivedA"); 

// derivedb.cpp (if listed second in the "ar" line, this does not get called) 
DerivedRegister<DerivedB> DerivedB::reg("DerivedB"); 

注意。

C++で静的変数を使用していても、何らかの理由でniceを再生できないarまたは静的ライブラリが欠けていますか?

答えて

10

直観とは逆に、リンクコマンド内のアーカイブを含めても、アーカイブ内のすべてのオブジェクトファイルを含むのと同じではありません。定義されていないシンボルを解決するために必要なアーカイブ内のオブジェクトファイルのみが含まれます。いったんダイナミックリンクがなくなれば、ライブラリの全体(Cライブラリと思う)が各実行可能ファイルに複製されることを考えれば、これは良いことです。

リンカは、コマンドラインで指定された場所でアーカイブを1回だけ検索します。これは、ld(1)のマニュアルページです。アーカイブが、コマンドラインでアーカイブの前に現れたオブジェクトの中で未定義のシンボルを定義している場合、リンカはアーカイブから適切なファイルをインクルードします。ただし、コマンド行の後に表示されるオブジェクトの未定義のシンボルによって、リンカーはアーカイブを再度検索することはありません。

残念ながら、アーカイブのすべてのメンバーをリンクされた実行可能ファイルに含める標準的な方法はありません。 linuxではg++ -Wl,-whole-archiveを使用でき、Mac OS Xではg++ -all_loadを使用できます。

だから、GNU binutilsのLDとして、リンクコマンドが

g++ -o testFactory -Wl,-whole-archive libbase.a -Wl,-no-whole-archive main.cpp 

する必要があります-Wl,-no-whole-archiveは、任意のアーカイブは通常の方法でリンクされます++グラムによって生成された最後のリンクコマンドの後半で登場することを保証します。

+0

ありがとう、これは私を正しい道のりにしました。将来の参考として、これも同様に役立ちました(全アーカイブの検索フーの改善に感謝します!) http://stackoverflow.com/a/842770/1322752 –

関連する問題