クラスから静的ライブラリを作成しようとしていますが、それを使用しようとすると、常に未定義の参照でエラーが発生します。私が進めた方法は、次のようなオブジェクトファイルを作成することでした
g++ -c myClass.cpp -o myClass.o
そして、それで梱包
ar rcs myClass.lib myClass.o
これには明らかに一般的に欠けているものがあります。シンボルのあるものだと思う。アドバイスをありがとう、私はそれがおそらくおそらく愚かなものに悩まされていくつかのチュートリアルを読んでいる場合、私が見つけることができるものであることを知っています:)
myClass.h:
class myClass{
public:
myClass();
void function();
};
myClass.cpp:
#include "myClass.h"
myClass::myClass(){}
void myClass::function(){}
クラスを使用するプログラム:
#include "myClass.h"
int main(){
myClass mc;
mc.function();
return 0;
}
最後に、次のようにコンパイルします。
g++ -o main.exe -L. -l myClass main.cpp
エラーは古典的なものです:
C:\Users\RULERO~1\AppData\Local\Temp/ccwM3vLy.o:main.cpp:(.text+0x31): undefined
reference to `myClass::myClass()'
C:\Users\RULERO~1\AppData\Local\Temp/ccwM3vLy.o:main.cpp:(.text+0x3c): undefined
reference to `myClass::function()'
collect2: ld returned 1 exit status
これはおそらくリンク順序の問題です。 GNUリンカがライブラリを認識すると、必要のないすべてのシンボルが破棄されます。この場合、ライブラリは.cppファイルの前に表示されるため、ライブラリは。 cppファイルがコンパイルされます。
g++ -o main.exe main.cpp -L. -lmylib
または
g++ -o main.exe main.cpp myClass.lib
Microsoftリンカーは、コマンドラインでのライブラリの順序を考慮しません。
別の考えられる原因:extern "C"
を忘れています。
C++プログラムをC静的ライブラリにリンクしようとしたため、これに遭遇しました。ライブラリのヘッダーにはextern "C"
がなかったため、リンカはマングルされた関数名を探していましたが、実際にはライブラリにはマングルされていない関数名がありました。
何が起こっているのかを理解するのに時間がかかったので、これが他の人の助けになることを願っています。
これは、リンカが出力コードを最適化する方法の問題です。 Lib_AとLib_Bの2つのライブラリを使用する実行可能ファイルがあるとします。 Lib_Aに依存Lib_BLib_Aはシンボルを定義します:Lib_A1およびLib_A2、およびLib_Bはシンボルを定義しますLib_B1およびLib_B2。ここで、実行可能ファイルがシンボルLib_A1のみを使用し、Lib_A1が使用すると仮定しますシンボルLib_B1Lib_Bで定義されています。シンボルLib_B1は、実行可能ファイルでは使用されません。
g++ .... -lLib_B -lLib_A
リンカーは次のように機能します。最初にリンクする実行可能ファイルLib_Bがあります。実行可能ファイルでシンボルLib_B1もLib_B2も使用されていないことがわかります。それらは不必要なので、私はそれらを未定義にします。後でリンカーを参照してください。ああ、別のライブラリがありますLib_A。実行可能ファイルはシンボルLib_B1を使用していることがわかります。そのままにして未使用のシンボルの定義を解除しますLib_B2。 Lib_B1がLib_A1を使用していることがわかりません。g++ ... -lLib_A -lLib_B
リンカーは次のように機能します。最初にリンクする実行可能ファイルLib_Aがあります。ああ、実行可能ファイルはLib_A1を使用していることがわかります。それらを保持し、未定義にしますLib_A2。後で見ることができます。ああ、別のライブラリがありますLib_B。既にリンクされたシンボルで実行可能になり、Lib_B1を使用していることがわかります。その結果、Lib_B1とLib_A1、未定義Lib_B2およびLib_A2。使用する:
g++ -o main.exe main.cpp myClass.lib
ライブラリパスと-lフラグの使用には問題が伴いますが、必要な場合は、ライブラリの名前をlibmylib.aに変更し、次のようにコンパイルします。
g++ -o main.exe main.cpp -L. -lmylib
また、移植性の理由から、ソースファイルまたは出力ファイルの名前に大文字と小文字を混在させることは一般的に悪い考えです。
これにより、リンクエラーが回避され、.so共有ライブラリが作成されます。
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true