オブジェクトファイル内の未解決の外部シンボル


180

Visual Studioでのコーディング中に、未解決の外部シンボルエラーが発生し、どうすればよいかわかりません。何が悪いのかわかりません。解読して頂けますか?どのようなエラーをどこで探すべきですか?

1>Form.obj : error LNK2019: unresolved external symbol "public: class Field * __thiscall Field::addField(class Field *)" (?addField@Field@@QAEPAV1@PAV1@@Z) referenced in function "public: void __thiscall Form::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse@Form@@QAEXAAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>Form.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall Field::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse@Field@@UAEXAAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: __thiscall InputField::InputField(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (??0InputField@@QAE@AAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::prompt(void)" (?prompt@Field@@UAEXXZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getName(void)" (?getName@Field@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getType(void)" (?getType@Field@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::describe(void)" (?describe@Field@@UAEXXZ)
1>C:\Users\tomy\Documents\Visual Studio 2010\Projects\zapoctovkac++\Debug\zapoctovkac++.exe : fatal error LNK1120: 6 unresolved externals

26
未解決のシンボルは、どこかで宣言したが定義されていないシンボルです。通常、これは、サードパーティライブラリのヘッダーファイルを#includeしたが、ライブラリに対応する.objファイルの場所をリンカーに伝えなかったことを意味します。
deong

7
よくある間違いは、関数をスタンドアロンとして定義し、.cppファイル でクラスセレクターを忘れてしまうことです。これを行うと(間違って) void myFunc() { /* do stuff */ } 、これの代わりに(右): void A::myFunc() { /* do stuff */ }
jave.web

次のように、.cppファイルでブラケットをさらに定義したくない場合は、ヘッダーファイルにブラケットを直接追加することもできますvoid myFunc() {};
Patapoom、2018

回答:


303

このエラーは、多くの場合、一部の関数には宣言がありますが、定義がないことを意味します。

例:

// A.hpp
class A
{
public:
  void myFunc(); // Function declaration
};

// A.cpp

// Function definition
void A::myFunc()
{
  // do stuff
}

あなたの場合、定義が見つかりません。問題は、いくつかの関数宣言をもたらすヘッダーファイルをインクルードしていることである可能性がありますが、次のいずれかです。

  1. cppファイルで関数を定義しないでください(このコードを自分で記述した場合)
  2. 定義を含むlib / dllファイルを含めないでください

よくある間違いは、関数をスタンドアロンとして定義A::し、.cppファイルなどでクラスセレクターを忘れてしまうことです。

間違った: void myFunc() { /* do stuff */ }
正しい: void A::myFunc() { /* do stuff */ }


2
上記のlibファイルをプロジェクトに含める方法は?
tmj 14

@tMJ使用している環境によって異なります。オンラインまたはこのサイトでチュートリアルを検索します。
Chris Morris

@ChrisMorris関数の定義は、適切にリンクしなかったなどの理由で利用できませんでした。ただし、dllはメモリ内になく、LoadLibrary呼び出しを介してロードする必要があったためです。(FTR)
tmj 2014

2
最後のアドバイスはまさにここの問題でした。のvoid myFunc() {}代わりにやっていましたA::void myFunc() {}
Charles、

素晴らしい答え。他の場所からメソッドをコピーした後、実際には(1)とA ::の両方を忘れていました。
RoG、2017年

24

参照しているソリューション内のすべてのソースファイルが含まれていることを確認します。

Fieldプロジェクトのクラスのソースファイル(つまり実装)を含めない場合、ビルドされず、コンパイル中にリンクできません。

あるいは、おそらく、静的または動的ライブラリを使用していて、リンカーに.libs を伝えるのを忘れているのですか?


3
正しいlibファイルを参照することで問題は解決しました。Project-> Properties-> Linker-> General-> Additional Library DirectoriesとProject-> Properties-> Linker-> Input-> Additional Dependenciesを使用して、libディレクトリとlibファイルを参照します
zak

11

ライブラリまたはインクルードが欠落しているようです。getName、getTypeなどが含まれているライブラリのクラスを特定し、それをヘッダーファイルに配置するか、を使用してみてください#include

また、これらが外部ライブラリからのものである場合は、プロジェクトファイルで参照するようにしてください。たとえば、このクラスがabc.libに属している場合、Visual Studio

  1. [プロジェクトのプロパティ]をクリックします。
  2. 「構成プロパティー」、「C / C ++」、「生成」に移動し、「追加の組み込みディレクトリー」の下のabc.libの場所を指していることを確認します。リンカー、入力の下で、追加の依存関係の下にabc.libがあることを確認します。

9

.cppファイルのmainから関数を呼び出すことができず、.hファイルで正しく宣言され、.cファイルで定義されないという問題が発生しました。リンカエラーが発生しました。その間、私は通常の.cファイルから関数を呼び出すことができます。おそらくそれは呼び出し規約に依存します。解決策は、すべての.hファイルに次のpreproc行を追加することでした。

#ifdef __cplusplus
extern "C"
{
#endif

そしてこれらは最後に

#ifdef __cplusplus
}
#endif

7

プロジェクトがx64プロジェクトとしてコンパイルされると、エラーが発生しました。そして、私はx86としてコンパイルされたライブラリを使用しました。

ライブラリをx64として再コンパイルし、それを解決しました。


5

新しいヘッダーファイルが追加され、このエラーが原因でこのエラーが発生し始める場合は、ライブラリを追加してを取り除く必要がありますunresolved external symbol

例えば:

#include WtsApi32.h

必要があります:

#pragma comment(lib, "Wtsapi32.lib") 

4

同じリンクエラーがありましたが、別のdllを参照していたテストプロジェクトからのものでした。_declspec(dllexport)エラーメッセージで指定された各関数の前に追加した後 、リンクはうまく機能していることがわかりました。


3

原因と対策に関するほとんどの点は、このスレッドのすべての貢献者によってカバーされていると思います。私の「未解決の外部」問題について指摘したいのですが、それはマクロとして定義されたデータ型が予想とは異なる方法で置き換えられ、その結果、問題の関数に誤った型が提供され、型付きの関数が定義されていないため、解決できなかった可能性があります。特に、C / C ++->言語の下に、「WChar_t As Built In Type」という属性があります。これは、「いいえ(/ Zc:wchar_t-)」として定義されているはずですが、私の場合はそうではありませんでした。


おかげで、これは私のセットアップから問題を引き起こします( 'いいえ(/ Zc:wchar_t
Noypi Gilas

2

上記のChris Morrisによる優れた回答に加えて、純粋に設定されていないが独自の実装ではない仮想メソッドを呼び出す場合に、この同じフォールトを受け取ることができる非常に興味深い方法を見つけました。これはまったく同じ理由です(コンパイラーがメソッドの実装を見つけられないため、不正が発生します)が、IDEはこの障害を最小限にとらえませんでした。

たとえば、次のコードでは、同じエラーメッセージのコンパイルエラーが発生します。

//code testing an interface
class test
{
   void myFunc(); 
}

//define an interface
class IamInterface
{
    virtual void myFunc();
}

//implementation of the interface
class IamConcreteImpl
{
    void myFunc()
    {
       1+1=2;
    }
}

ただし、IamInterface myFunc()を純粋な仮想メソッド(「実装する必要がある」メソッド、つまり「オーバーライドできる」メソッドである仮想メソッドよりもメソッド)に変更すると、コンパイルエラーが解消されます。

//define an interface
class IamInterface
{
    virtual void myFunc() = 0;
}

これが次のStackOverFlow担当者がコードをステップ実行するのに役立つことを願っています!



2

必ずヘッダーファイルを装飾してください

#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H

// your header code here

#endif

これを含む悪いことは、あなたがそうしないと起こる可能性があります


8
使用してみ#pragma onceませんか?
アレンリナトック2015

2

さらに別の考えられる問題(私はしばらく頭を悩ませただけです):

関数をとして定義する場合inline、それらは(もちろん!)cppではなく、ヘッダー(またはインラインファイル)で定義する必要があります。 私の場合、それらはインラインファイルにありましたが、それらはプラットフォーム固有の実装であり、cppにはこの対応するinlが含まれていたためです
にはヘッダーの代わりにファイルが。ええ、s ** tが起こります。

これもここに置いておきたいと思いました。多分誰かが同じ問題に遭遇し、ここでそれを見つけました。


1
これに反対票を投じた人に:回答を間違っている、または役に立たないと思う理由を少なくともコメントに残してください。コメントのない反対投票は、せいぜい価値がありません。
Johann Studanski

1

私はこれで苦労しました。すべてが論理的にセットアップされました。コンストラクタを宣言しましたが、定義しませんでした

class SomeClass
{
   SomeClass();  // needs the SomeClass::SomeClass(){} function defined somewhere, even here
}

初歩的なものを忘れたとき、キーボードに頭をぶつけそうになりました。


1

久しぶりにC ++を実行していますが、関数定義にClassName ::接頭辞を追加し忘れたときにこのエラーが発生します。これはC ++に少し固有であるためです。だから、それもチェックすることを忘れないでください!


1

このリンカーエラーの考えられる原因の1つinlineは、宣言されているが、別の場所に含まれているヘッダーファイルで定義されていない関数である可能性もあります。インライン関数は、使用されるすべての翻訳単位で定義する必要があります。


0

ポインター

私はこの問題を抱えており、ポインターを使用して解決しました。これはあなたの問題ではなかったと思いますが、1時間前にこれを見たときにここにあればよかったので、私はそれを言及したいと思いました。私の問題は、静的メンバー変数を定義せずに宣言することでした(他の設定の後に来る必要がある定義)。もちろん、ポインターは定義を必要としません。同じく初等間違い:P


3
ここでは例が非常に役立ちます。
moffeltje

0

私の問題は、sconscriptにcppファイルが定義されていないことでした。Visual Studio cppにはプロジェクト内のファイルがありますが、何か完全にビルドされているため、これは非常に混乱する可能性があります。


0

私の問題は:フォワード宣言をしなければならなかった、「外部の未解決」のアクターであるクラスの。

エラーが発生したファイルに、次のように入力する必要がありました。

#include "ClassB" 

class ClassB; // this solved the problem

class ClassA{
    void foo(){
        ClassB* tmp = new ClassB();
        // ...
    }
};

もちろん、私のプロジェクトはもっと複雑で、これはほんの一部の例です。また、名前空間を使用する場合は、それらも宣言します


0

数時間を費やして、問題が私のメインファイルの.c代わりに拡張子があったことがわかりました.cpp

:/


0

チェックするさらに別の可能性、それは今回の私の問題でした。

ライブラリに関数を追加し、ライブラリの出力フォルダーを検索パスに含めました。

しかし、以前にリストされたライブラリの古いバージョンを含むフォルダーもあったため、VSは古いライブラリを使用しており、もちろん新しい関数を見つけることができませんでした。


0

挿入または抽出演算子をインライン関数としてオーバーロードしないようにしてください。私はこの問題を抱えていて、そのキーワードを削除したときだけそれは消えました。


0

私の場合それを引き起こしたもの:

Foo.cppFoo.hのない巨大なファイルがありました。Foo.cppこのように始まりました:

// ... 100 LOC here ...
namespace NS {
// ... 100 more LOC here ...
static int var;

「static」キーワードを削除し、Foo.hこれにa を追加しました:

extern int var;

間違いはありますか?

名前空間宣言が他のコードに埋め込まれていたため、varが元々名前空間で定義されていたことがまったくありませんでした。修正は次のように外部を変更することです:

namespace NS {
     extern int var;
}

0

「未解決の外部シンボル」エラーの考えられる理由は、関数呼び出し規約である可能性があります。

すべてのソースファイルが同じ標準(.cまたは.cpp)を使用していることを確認するか、呼び出し規約を指定してください。

それ以外の場合、1つのファイルがCファイル(source.c)であり、別のファイルが.cppファイルであり、それらが同じヘッダーにリンクしている場合、関数は最初に次のように定義されるため、「未解決の外部シンボル」エラーがスローされます。 C cdecl関数ですが、同じヘッダーを使用するC ++ファイルはC ++関数を探します。

「未解決の外部シンボルエラー」を回避するには、関数呼び出し規約がそれを使用するファイル間で同じに保たれていることを確認してください。


0

リンカエラーの前の行を詳しく調べる前に、考えられる説明を求めてここに来ました。グローバル宣言が欠落していた追加の実行可能ファイルであることが判明しました!


0

同じエラーが発生;{}たので、ヘッダーファイルをに置き換えることで回避できました。

#ifndef XYZ_h
#define XYZ_h
class XYZ
{
    public:
    void xyzMethod(){}
}
#endif

それがvoid xyzMethod();コンパイルされたくなかったとき。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.