C++ でプロジェクトをビルドするとき、特に他の人のコードを拾うときは、リンク エラーのデバッグが難しいことに気付きました。リンクエラーをデバッグして修正するために人々はどのような戦略を使用しますか?
3 に答える
あなたの専門知識のレベルはわかりませんが、ここに基本があります。
以下はVS2005からのリンカーエラーです-はい、あなたがそれに精通していないなら、それは巨大な混乱です。
ByteComparator.obj : error LNK2019: unresolved external symbol "int __cdecl does_not_exist(void)" (?does_not_exist@@YAHXZ) referenced in function "void __cdecl TextScan(struct FileTextStats &,char const *,char const *,bool,bool,__int64)" (?TextScan@@YAXAAUFileTextStats@@PBD1_N2_J@Z)
注目すべき点がいくつかあります。
- "ByteComparator.obj"-ByteComparator.cppファイルを探します。これがリンカーの問題の原因です。
- "int __cdecl does_not_exist(void)"-これは見つからなかったシンボルです。この場合、does_not_exist()という名前の関数です。
この時点で、多くの場合、解決するための最速の方法は、この関数のコードベースを検索し、実装がどこにあるかを見つけることです。関数が実装されている場所がわかったら、2つの場所がリンクされていることを確認する必要があります。
VS2005を使用している場合は、「プロジェクトの依存関係...」の右クリックメニューを使用します。gccを使用している場合は、実行可能ファイルの生成ステップ(gccは一連の.oファイルで呼び出されます)のmakefileを調べて、欠落している.oファイルを追加します。
2番目のシナリオでは、コードがない「外部」依存関係が欠落している可能性があります。Win32ライブラリは、リンクする必要のある静的ライブラリに実装されることがよくあります。この場合、MSDNまたは「MicrosoftGoogle」に移動してAPIを検索します。APIの説明の下部に、ライブラリ名が示されています。これをプロジェクトプロパティの[構成プロパティ]->[リンカー]->[入力]->[追加の依存関係]リストに追加します。たとえば、MSDNの関数timeGetTime()のページでは、ページの下部にあるWinmm.libを使用するように指示されています。
私が遭遇した一般的なリンク エラーの 1 つは、関数が定義された方法とは異なる方法で使用された場合です。このようなエラーが表示された場合は、使用するすべての関数が .h ファイルで適切に宣言されていることを確認する必要があります。
また、関連するすべてのソース ファイルが同じ lib ファイルにコンパイルされていることを確認する必要があります。私が遭遇したエラーは、2 つの別個のライブラリにコンパイルされた 2 つのファイル セットがあり、ライブラリ間で相互呼び出しを行う場合です。
思い当たる失敗はありませんか?
多くの場合、C ランタイム ライブラリが最大の原因です。すべてのプロジェクトで、シングルとマルチスレッド、および静的と DLL の設定が同じであることを確認します。
MSDN のドキュメントは、特定の Win32 API 呼び出しが欠落している場合に必要なライブラリを指摘するのに適しています。
それ以外は、通常、verbose フラグをオンにして、手がかりを探して出力を調べることになります。