8

以下は私が実行するものです

D:\Just4Fun\software\>make -f Makefile.hands stest
g++.exe -g -D_WIN32_WINNT=0x0601 -ID:\Boost\boost_1_51_0 -LD:\Boost\boost_1_51_0\stage\lib -LD:\MinGW\lib -lboost_system-mgw46-d-1_51 -lboost_filesystem-mgw46-d-1_51 -lboost_iostreams-mgw46-d-1_51 -lws2_32 -lwsock32 -o TestSerial.exe TestSerial.cpp

以下はその結果です

C:\Users\oleg\AppData\Local\Temp\ccXpC7RG.o: In function 'ZN5boost4asio6detail17winsock_init_base7startupERNS2_4dataEhh': D:/Boost/boost_1_51_0/boost/asio/detail/impl/winsock_init.ipp:39: undefined reference to 'WSAStartup@8'C:\Users\oleg\AppData\Local\Temp\ccXpC7RG.o: In function 'ZN5boost4asio6detail17winsock_init_base7cleanupERNS2_4dataE': D:/Boost/boost_1_51_0/boost/asio/detail/impl/winsock_init.ipp:48: undefined reference to 'WSACleanup@0' collect2: ld returned 1 exit status make: *** [stest] Error 1

以下は、言及されたsymoblsに関してライブラリをチェックした結果です(適切な方法でフォーマットできませんでした)

`d:\ MinGW \ lib> nm -C libws2_32.a | grep WSAStartup
00000000 T WSAStartup @ 8
00000000 I imp _WSAStartup @ 8

d:\ MinGW \ lib> nm -C libws2_32.a | grep WSACleanup
00000000 T WSACleanup @ 0
00000000 I imp _WSACleanup @ 0

d:\ MinGW \ lib> nm -C libwsock32.a | grep WSACleanup
00000000 T WSACleanup @ 0
00000000 I imp _WSACleanup @ 0

d:\ MinGW \ lib> nm -C libwsock32.a | grep WSAStartup
00000000 T WSAStartup @ 8
00000000 I imp _WSAStartup @ 8`

ご覧のとおり、ライブラリにはシンボルが存在し、ライブラリは対応する-Lコマンドラインオプションで参照される場所にあります。
では、なぜ「未定義の参照」????

4

1 に答える 1

16

これは非常に一般的なエラーですが、非常に簡単な解決策があります。リンクするライブラリをソース ファイルとオブジェクト ファイルの後に配置します。


オブジェクト (またはソース) ファイル A がライブラリ B に依存している場合、リンク時にコマンド ラインで A を B の前に指定する必要があります。これは、GNU (およびおそらく他の) リンカーがシンボルの依存関係を解決する方法によるものです。

反対の(そして間違った)方法でそれを行う場合

g++ -lB A.cpp

次に、リンカーがライブラリ B をロードすると、ライブラリ内のどの関数にも依存関係がないため、リンカーはそのライブラリを破棄します。

したがって、正しい方法は、ライブラリを最後に配置することです

g++ A.cpp -lB

これが、多くの例で常にライブラリをコマンド ラインの最後に置く理由です。

したがって、質問のコマンドラインについては、代わりに

g++.exe -g -D_WIN32_WINNT=0x0601 -ID:\Boost\boost_1_51_0 \
    -LD:\Boost\boost_1_51_0\stage\lib -LD:\MinGW\lib \
    -o TestSerial.exe TestSerial.cpp \
    -lboost_system-mgw46-d-1_51 -lboost_filesystem-mgw46-d-1_51 -lboost_iostreams-mgw46-d-1_51 -lws2_32 -lwsock32

この順序は、ライブラリ間の依存関係にも重要です。ライブラリ L1 がライブラリ L2 に依存している場合、L1 はコマンド ラインで L2 の前になければなりません。

于 2012-09-18T08:04:05.313 に答える