リンカーのエラー:LNK2000 ~ LNK2014

以下の表では,第 1 列に,エラーが検知された時に返されるエラー番号を一覧表示しています。第 2 列の第 1 行は,メッセージ・テキストを示しています。第 2 列の第 2 行目以降は,メッセージの説明を示しています。

番号 メッセージ・テキストと説明
LNK2001 unresolved external symbol "symbol"

リンカーが検索した全てのライブラリーやオブジェクト・ファイルで見つけることができない何か (関数,変数,またはラベルなど) をコードが参照している場合,コードがこのエラー・メッセージを生成します。一般に,このエラーの発生には 2 つの理由があります。コードが存在しないものを参照した場合 (たとえば,シンボルのスペルが間違っている,または大文字小文字の区別を行っていない) や,コードが間違ったものを参照した場合 (製品のあるバージョンが提供しているライブラリーと他のバージョンが提供しているライブラリーといったライブラリーの混在したバージョンを使用している) です。

使用している呼び出し規約に依存して,アットマーク (@) と数字がシンボル名に付加しなければならないことがあります (詳細は,「ATTRIBUTES プロパティと呼び出し規約」を参照)。

コーディングとビルドのエラーの様々な種類が LNK2001 を引き起こします。様々な原因を以下に示し,より詳細な説明を行っています。

コーディングの問題

  • Fortran プログラムでは,LNK2001 メッセージの原因は以下の 1 つです。

    • ルーチンが宣言されたものと異なる引数の数や間違った引数型でルーチンを呼び出した場合に発生します。引数の数を意識的に不一致にしたい場合,Fortran OPTIONAL 属性 (明示的インタフェースが必要) を使用するか,!DEC$ ATTRIBUTES C を使用して呼び出されるルーチンに C 属性を与えます (これは,呼び出されるルーチンと呼び出すルーチンの両方で指定しなければなりません)。詳細は,「言語が混在したプログラミングの問題点」を参照してください。

    • Visual Fortran ライブラリー・ルーチン名に対する未解決の参照は,そのルーチンが要求する適切な USE 文を省略したために発生します。たとえば,TRACEBACKQQ ルーチンの呼び出しは USE DFLIB 文を要求し,DLGINITUSE DFLOGM を要求します。同様に,IMSL ルーチンを呼び出すには特定の USE 文が必要になりますし,CXML ルーチンを呼び出すには特定の INCLUDE 文が必要になります。

    • _WinMain@16 に対する未解決の参照は,典型的なアプリケーションに対して Fortran Windows としてプロジェクト・タイプを指定した場合に発生します (Fortran Windows アプリケーションは,WinMain 関数の宣言とインタフェースを必要とします)。この場合,正しいプロジェクト・タイプ (たとえば,Fortran Console) で新しい Fortran プロジェクトを作成し,新しいプロジェクト・ディレクトリにファイルをコピーし,新しいプロジェクトにそれらを追加します (「プロジェクトの定義」を参照)。

    • 呼び出しているルーチンが Win32 API ルーチンの場合,「Project Settings」ダイアログボックス (「Project」メニューの「Settings」をクリック) の「Link」タブをクリックし,「Object/Library modules」欄にそのライブラリーを指定する必要があります。必要なライブラリーを知るには,『Platform SDK』のルーチンの説明を読みます (詳細は,「Win32 ルーチンの呼び出し」を参照)。

  • コードとモジュール定義 (.DEF) ファイルでの大文字小文字の不一致は,LNK2001 を引き起こします。たとえば,1 つの C++ ソース・ファイルで変数を "var1" と名付け,他のソース・ファイルでそれを "VAR1" で参照しようとした場合,このエラーが発生します。これを解決するには,全ての参照でシンボルの大文字小文字が正確に一致するようにすることです。

  • 関数のインライン展開を使っているプロジェクトで,その関数をヘッダ・ファイルではなく .CPP ファイルで定義している場合,LNK2001 エラーが発生します。

  • C++ を使用している場合,C++ から C 関数を呼び出す時,extern "C" を使用していることを確認してください。extern "C" を使用することで,強制的に C の名前付け規約を使用するようにします。ファイル拡張子に関係なく C (/Tc) または C++ (/Tp) ファイルとしてファイルを強制的にコンパイルする,/Tp または /Tc のようなコンパイラ・オプションに注意してください。そうしなければ,自分が期待したものとは異なる関数名を得ることになるかもしれません。

  • 外部リンケージを持たない関数またはデータを参照しようとすると,LNK2001 が発生します。C++ では,インライン関数と const データは,明示的に extern を指定することを除いて,内部リンケージを持ちます。

  • 関数本体または変数がない場合,LNK2001 が発生します。関数プロトタイプまたは extern 宣言だけを持っている場合,コンパイラはエラーなしに継続されますが,リンカーはアドレスに対する呼び出しまたは変数の参照を解決することができません。これは,関数コードまたは変数がないためです。

  • 名前の装飾は,最終的に装飾された関数名に関数の引数を取り込みます。関数宣言で定義した引数型と一致しない引数型を持つ関数を呼び出した時に,LNK2001 が発生します。

  • 正しくインクルードされていないプロトタイプは,コンパイラが関数本体が提供されていないと判断する原因になります。関数 F のクラスおよび非クラスのインプリメンテーションを持つ場合,C++ のスコープ解決規則に注意してください。

  • C++ を使用する場合,クラス定義のプロトタイプだけでなく,クラスに対する特定の関数のインプリメンテーションが取り込まれていることを確認してください。

  • 抽象基本クラスのコンストラクタやデストラクタから純粋仮想関数を呼び出そうとした場合,LNK2001 が発生します。これは,純粋仮想関数の定義によって,純粋仮想関数には基本クラスのインプリメンテーションがないからです。

  • グローバル関数と変数のみがパブリックです。

    定義で static 修飾子で宣言された関数は,ファイル スコープを持ちます。静的変数にも同じ制限があります。静的変数が宣言されたファイルの外部から静的変数を参照しようとすると,コンパイル・エラーまたは LNK2001 になります。

    関数の内部で宣言された変数 (ローカル変数) は,その関数のスコープ内だけで使うことができます。

    C++ のグローバル定数は,static リンケージを持ちます。この点が C と異なります。C++ の複数のファイルでグローバル定数を使おうとすると,LNK2001 が発生します。対策として,const 初期化をヘッダ・ファイルにインクルードし,関数プロトタイプと同じように必要に応じてヘッダ・ファイルを .CPP ファイルにインクルードします。別の対策として,変数を非定数にし,変数が参照される時に定数参照を使う方法もあります。

コンパイルとリンクの問題

  • リンク時に必要とされる実行時ライブラリーの名前は,コンパイラによってオブジェクト・モジュール・ファイルにインクルードされています。/NOD (/NODEFAULTLIB) オプションを使用した場合,明示的にそれらのライブラリーをインクルードした場合を除いて,それらのライブラリーはプロジェクトにリンクされません。この場合,/NOD を使用すると,LNK2001 が発生します。

  • ユニコードと MFC を使用している場合,wWinMainCRTStartup へのエントリ・ポイントを作成していなければ,_WinMain@16 で未解決の外部参照が発生します。/ENTRY オプションを使用するか,「Project Settings」ダイアログボックス (「Project」メニューの「Settings」をクリック) の「Link」タブをクリックし,「Output」カテゴリを選択し,「Entry-point symbols」欄にこの値を入力します。

  • 詳細は,以下の『Microsoft Knowledge Base』記事を参照してください (MSDN をインストールしていれば MSDN を検索するか,ウェッブ・ブラウザを使って http://support.microsoft.com/default.aspx? から以下の記事の Q 番号で検索します)。

    • Q125750 "PRB: Error LNK2001: '_WinMain@16': Unresolved External Symbol"
    • Q131204 "PRB: Wrong Project Selection Causes LNK2001 on _WinMain@16"
    • Q100639 "Unicode Support in the Microsoft Foundation Class Library"

  • /MT とライブラリー LIBC.LIB を指定してコンパイルしたコードをリンクすると,_beginthread_beginthreadex_endthread,および _endthreadex で LNK2001 が発生します。

  • /MD でコンパイルすると,ソースでの "func" への参照がオブジェクト・ファイルでは "__imp__func" への参照になります。これは,全ての実行時の内容が DLL 内で保持されるためです。スタティック・ライブラリー LIBC.LIB または LIBCMT.LIB とリンクしようとすると,__imp__func で LNK2001 が発生します。/MD なしでコンパイルした時,MSVCxx.LIB とリンクしようとすると,LNK2001 が必ずしも発生しませんが,他の問題が発生します。

  • 明示的または暗黙の /ML でコンパイルしたコードと LIBCMT.LIB をリンクすると,_errno で LNK2001 が発生します。

  • アプリケーションのデバッグ・バージョンをビルドする時に,リリース・モードのライブラリーとリンクすると,LNK2001 が発生します。同様に,/Mxd オプション (/MLd/MTd,または /MDd) を使用し, _DEBUG を定義し,リリース・モードのライブラリーとリンクすると,未解決の外部参照が潜在的に発生します (他の問題の中で)。

  • 異なったバージョンの Microsoft ライブラリーとコンパイラ製品の混在が問題を引き起こします。新しいバージョンのコンパイラ・ライブラリーは,前のバージョンに含まれるライブラリーにはない新しいシンボルを含んでいます。シンボルが 32 ビット・オブジェクト・ファイルまたはライブラリーになるかどうかは,DUMPBIN を使って調べます。

  • 現在,コンパイラ・ベンダ間またはコンパイラの異なったバージョン間で C++ の名前付けに標準がありません。そのため,他のコンパイラでコンパイルしたオブジェクトをリンクする場合,同じ名前付け規約で生成されず,結果として LNK2001 が発生します。

  • 異なったモジュールでインラインと非インラインのコンパイル・オプションを混在させると,LNK 2001 が発生します。関数インライン展開をオン (/Ob1 または /Ob2) にして C++ ライブラリーを作成し,対応する関数を記述したヘッダ・ファイルがインライン展開をオフ (インライン・キーワードなし) で作成された場合,このエラーが発生します。この問題を防ぐには,他のファイルにインクルードしようとするヘッダ・ファイルに inline として定義したインライン関数を持たせます。

  • Visual C++ #pragma inline_depth コンパイラ指示文を使用している場合,2 以上の値が設定され,/Ob1 または /Ob2 コンパイラ・オプションを使用していることを確認してください。

  • リソースのみの DLL を作成する時に,/NOENTRY リンク・オプションを省略すると,LNK2001 が発生します。

  • 不正な /SUBSYSTEM または /ENTRY の設定を使用すると,LNK2001 が発生します。たとえば,キャラクタ・ベースのアプリケーション (Console アプリケーション) を作成し,/SUBSYSTEM:WINDOWS を指定すると,WinMain に対する未解決の外部参照が発生します。詳細は,/SUBSYSTEM/ENTRY リンカー・オプションを参照してください。

エクスポートの問題

  • 16 ビットから 32 ビットにアプリケーションを移植する時,LNK2001 が発生します。現在の 32 ビット・モジュール定義 (.DEF) ファイルの形式は,__cdecl__stdcall,および __fastcall 関数が下線なしで (装飾なし) で EXPORTS セクションにリストされていることを要求します。これは,それらが下線で (装飾されて) リストされなければならない 16 ビット形式と異なっています。詳細は,モジュール定義ファイルの EXPORTS セクションの説明を参照してください。

  • .DEF にリストされ,見つからないエクスポートが LNK2001 を引き起こします。これは,それが存在しない,スペルが間違っている,または装飾された名前 (.DEF ファイルは装飾された名前を取りません) を使用してるためです。このエラー・メッセージに続いて,致命的なエラー LNK1120 が表示されます。

以下の節では,上記の一覧の名前の問題について詳述します。

  • 関数本体または変数がない

    関数プロトタイプのみを持っている場合,コンパイラはエラーなしに継続されますが,関数コードまたは変数がないため,リンカーはアドレスへの呼び出しを解決できません。リンカーが解決しなければならない関数への実際の呼び出しを作成するまで,このエラーは発生しません。

  • 名前装飾

    通常,これは C++ 名前付け規約を指しますが,C++ 以外でも同様に適用されます。基本設定では,C++ は,関数名の計算に関数名,引数,および返し値を使用します。

    C++ プログラムから C 関数を呼び出す時,extern "C" を使用します。extern "C" は,クラスではない C++ 関数に対して C 名前付け規約を強制的に使用させます。

LNK2003 gp relative fixup to symbol not in .sdata "module"

型のインスタンスをコンパイルする時に指定した /Gt 値が,型の参照をコンパイルする時に指定した値と異なっています。/Gt に対して一貫した値を指定して,オブジェクト・ファイルを再ビルドしてください。このエラーに続いて,致命的なエラー LNK1165 が表示されます。

LNK2004 gp relative fixup overflow; sdata section ("section") is too large

.sdata セクションが大きすぎます。/Gt に小さい値を指定して,再ビルドしてください。このエラーに続いて,致命的なエラー LNK1165 が表示されます。

LNK2005 symbol already defined in object

装飾された書式で表示される与えられたシンボルは,二重に定義されていました。以下の 1 つが原因と考えられます。

  • このエラーの多くの共通した理由は,シングルスレッドとマルチスレッド・ライブラリーの両方と間違ってリンクされた,スタティックとダイナミック・ライブラリーの両方と間違ってリンクされた,または,デバッグと非デバッグ・バージョンの両方と間違ってリンクされたことです。アプリケーション・プロジェクトが適切なライブラリーのみを含み,他社製ライブラリーがシングルスレッドまたはマルチスレッド・バージョンを適切に作成している,または,スタティックまたはダイナミック・ライブラリーを適切に作成していることを確認してください。

    Fortran と C ライブラリーの型が一致していなければなりません。詳細は,「一貫性のあるライブラリー形式の指定」を参照してください。

  • 与えられたシンボルがパッケージ関数 (/Gy でコンパイルして作成) で,1 つ以上のファイルにインクルードされましたが,コンパイル間で変更されていました。シンボルを含む全てのファイルを再コンパイルしてください。

  • 与えられたシンボルが異なったライブラリーの 2 つのメンバ・オブジェクトで異なって定義されており,両方のメンバ・オブジェクトが使用されていました。

  • 絶対シンボルが 2 度定義され,それぞれの定義で異なった値を持っていました。

このエラーに続いて,致命的なエラー LNK1169 が表示されます。

LNK2006 TOC relative fixup to symbol not in TOC "name"; fixup ignored

LINK は不正なフィックスアップを発見し,それを無視しました。

LNK2007 TOC relative fixup overflow; TOC is too large; fixup ignored

LINK は不正なフィックスアップを発見し,それを無視しました。

LNK2008 Fixup target is not aligned "alignment"

LINK は,適切に位置あわせされていないオブジェクト・ファイルにフィックスアップのターゲットを発見しました。

LNK2009 Fixup target must be absolute "name" w/o -FIXED; fixup ignored

LINK は不正なフィックスアップを発見し,それを無視しました。

LNK2010 Duplicate IMGLUE relocations for "name"

LINK は,オブジェクト・ファイルに "name" に対する重複した再配置を発見しました。オブジェクト・ファイルはおそらく壊れています。詳細は,「壊れたオブジェクト・ファイル」を参照してください。

LNK2011 precompiled object not linked in; image may not run

プリコンパイル済みヘッダを使用する場合,プリコンパイル済みヘッダと一緒に作成された全てのオブジェクト・ファイルをリンクしなければなりません。他のソース・ファイル用にプリコンパイル済みヘッダを作成するために使用するソース・ファイルを持っている場合,プリコンパイル済みヘッダと一緒に作成したオブジェクト・ファイルをインクルードしなければなりません。

LNK2012 No NOP following relocationtype relocation to "symbol"

TOCINDIRCALL および TOCCALLREL は,このタイプの再配置を持つ命令の次に NOP を必要とします。これは,コンパイラまたはアセンブラ開発者が Microsoft リンカーを使用するときに便利です。

LNK2013 Fixup overflow. Target "symbol" is out of range

このエラーは実行形式ファイルが大きすぎる時に発生するか,エラーが機械語コードでの問題を示しています。この問題を回避するには,以下を行います。

  • 共有ライブラリーを使用します。

  • 大域データが定義されたモジュール以外のモジュールから参照される場合,TOC 空間が必要です。そのようなデータを参照するモジュールにこれを移動することで,TOC 空間を削除することができます。しかしながら,データが複数のモジュールで参照されている場合,空間を節約するために TOC 空間を削除することはできません。

LNK2014 TLS relative fixup overflow; .tls section ("section") is too large

スレッド・ローカル領域 (.tls) 用に作成されたセクションが大きすぎます。TLS データは 32 KB 以内でなければなりません。このデータは,このデータの宣言と定義で __declspec(thread) 記憶クラス修飾子を使って作成されます。この問題を回避するには,以下を行います。

  • コード中のスレッド・ローカル・データの量を減らします。

  • TlsAlloc および TlsFree のような関数を呼び出してダイナミック TLS を使用します。