エラーLNK2019を解決する方法:未解決の外部シンボル-関数?

2013年11月10日に質問されました。  ·  閲覧回数 472.1k回  ·  ソース

phibao37 picture
2013年11月10日

このエラーが発生しましたが、修正方法がわかりません。

Visual Studio2013を使用しています。ソリューション名をMyProjectTestにしました。これはテストソリューションの構造です。

The structure

--function.h

#ifndef MY_FUNCTION_H
#define MY_FUNCTION_H

int multiple(int x, int y);
#endif

-function.cpp

#include "function.h"

int multiple(int x, int y){
    return x*y;
}

--main.cpp

#include <iostream>
#include <cstdlib>
#include "function.h"
using namespace std;

int main(){
    int a, b;
    cin >> a >> b;
    cout << multiple(a, b) << endl;

    system("pause");
    return 0;
}

私は初心者です。 これは単純なプログラムであり、エラーなしで実行されます。 インターネットで読んで単体テストに興味を持ったので、テストプロジェクトを作成しました。

ファイル>新規>プロジェクト...>インストール済み>テンプレート> Visual C ++>テスト>ネイティブ単体テストプロジェクト>

名前: UnitTest1ソリューション:ソリューションに追加次に、現在開いているソリューションのパスに自動切り替えされた場所これはソリューションのフォルダー構造です。

Folder structure

私はファイルunittest1.cppのみを編集しました:

#include "stdafx.h"
#include "CppUnitTest.h"
#include "../MyProjectTest/function.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTest1
{       
    TEST_CLASS(UnitTest1)
    {
    public:

        TEST_METHOD(TestEqual)
        {

            Assert::AreEqual(multiple(2, 3), 6);
            // TODO: Your test code here
        }

    };
}

しかし、エラーLNK2019:未解決の外部シンボルが表示されます。 関数multipleの実装が欠落していることを私は知っています。 function.cppファイルを削除しようとしましたが、宣言を定義に置き換えて実行しました。 ただし、宣言と定義の両方を同じファイルに書き込むことはお勧めしません。 それを行わずにこのエラーを修正するにはどうすればよいですか? ファイルunittest.cppの#include "../MyProjectTest/function.cpp"に置き換える必要がありますか? (私は英語があまり得意ではありません。ありがとう)

回答

kevintodisco picture
2013年11月10日
83

1つのオプションは、 UnitTest1プロジェクトにfunction.cppを含めることですが、これは最も理想的なソリューション構造ではない場合があります。 あなたの問題に対する簡単な答えは、 UnitTest1プロジェクトをビルドするとき、コンパイラとリンカはfunction.cppが存在することを知らず、 multiple定義を含むリンクも何もないということです。

あなたのユニットテストは別のプロジェクトにあるので、あなたの意図はそのプロジェクトをスタンドアロンのユニットテストプログラムにすることだと思います。 テストしている関数を別のプロジェクトに配置すると、そのプロジェクトを動的または静的にリンクされたライブラリにビルドすることができます。 静的ライブラリはビルド時に他のプログラムにリンクされ、拡張子は.libで、動的ライブラリは実行時にリンクされ、拡張子は.dllです。 私の答えとしては、静的ライブラリを好みます。

プロジェクトのプロパティで変更することにより、最初のプログラムを静的ライブラリに変えることができます。 プロジェクトが実行可能ファイル( .exe )にビルドするように設定されている[全般]タブの下にオプションがあるはずです。 これを.lib変更できます。 .libファイルは.exeと同じ場所にビルドされます。

UnitTest1プロジェクトで、そのプロパティに移動し、[追加のライブラリディレクトリ]カテゴリの[リンカー]タブで、 MyProjectTestビルドされるパスを追加します。 次に、[リンカー-入力]タブの[追加の依存関係]に、静的ライブラリの名前(おそらくMyProjectTest.lib )を追加します。

これでプロジェクトをビルドできるようになります。 これを行うことにより、必要に応じてビルドプロパティを変更しない限り、 MyProjectTestはスタンドアロンの実行可能プログラムにならないことに注意してください。これは理想的とは言えません。

Niyaz Ivanov picture
2013年11月10日
39

Visual Studioソリューションツリーで、プロジェクト 'UnitTest1'を右クリックし、[追加]-> [既存のアイテム]->ファイルを選択します../MyProjectTest/function.cpp

harrygg picture
2015年06月05日
17

プロジェクトをスタンドアロンEXEにコンパイルしたいので、UnitTestプロジェクトをfunction.cppから生成されたfunction.objファイルにリンクすると機能します。 「UnitTest1」プロジェクトを右クリック>構成プロパティ>リンカー>入力>追加の依存関係>「.. \ MyProjectTest \ Debug \ function.obj」を追加

Kevin Dill picture
2015年12月23日
10

Visual Studio 2013でこの問題が発生したばかりです。どうやら今、同じソリューションに2つのプロジェクトがあり、依存関係を設定するだけでは不十分です。 それらの間にプロジェクト参照を追加する必要があります。 それを行うには:

  1. ソリューション探索でプロジェクトを右クリックします
  2. [追加] => [参照...]をクリックします。
  3. [新しい参照の追加]ボタンをクリックします
  4. このプロジェクトが依存しているプロジェクトのチェックボックスをオンにします
  5. [OK]をクリックします
cahit beyaz picture
2016年06月05日
8

.cppファイルで.cファイルを使用していたことが判明しました。 .cの名前を.cppに変更すると、問題が解決しました。

zar picture
2017年10月06日
6

(私がそうであったように)このリンカーエラーを取得する別の方法は、クラスのインスタンスをdllからエクスポートしているが、そのクラス自体をインポート/エクスポートとして宣言していない場合です。

 #ifdef  MYDLL_EXPORTS 
    #define DLLEXPORT __declspec(dllexport)  
 #else
    #define DLLEXPORT __declspec(dllimport)  
 #endif

class DLLEXPORT Book // <--- this class must also be declared as export/import
{
public: 
    Book();
    ~Book();
    int WordCount();
};

DLLEXPORT extern Book book; // <-- This is what I really wanted, to export book object

したがって、主に上記のbookというBookクラスのインスタンスのみをエクスポートしていましたが、 Bookクラスをエクスポート/インポートクラスとして宣言する必要がありました。それ以外の場合はbook.WordCount()呼び出す必要がありました。他のdllでリンクエラーが発生していました。

Enyx picture
2018年02月28日
3

これは私に起こったので、私はそれがそうであったのと同じくらい簡単に、私の解決策を共有するかもしれないと思いました:

[構成のプロパティ] -> [一般] -> [文字セット]で両方のプロジェクトの文字セットを確認します

私のUnitTestプロジェクトはデフォルトの文字セットマルチバイトを使用していましたが、ライブラリはUnicodeにあります。
私の関数はTCHARをパラメーターとして使用していました。 その結果、ライブラリでTCHAR変換されましたが、 UnitTestではchar *でした。パラメーターが実際には同じではなかったため、シンボルが異なっていました。

Mushy picture
2017年10月11日
1

クラス内で宣言された関数の定義を提供するのを忘れた場合、Visual Studio 2015でのコンパイル中にLNK2019が発生することを発見しました。

リンカエラーは非常にわかりにくいものでしたが、エラーを読んで不足しているものを絞り込み、これをクリアするためにクラス外の定義を提供しました。

pivnothebearrrrrrrrr picture
2020年04月22日
1

私の場合、プロパティでcppファイルを「C / C ++コンパイラ」に設定します->一般的にLNK2019エラーを解決します。

Nejc Galof picture
2017年08月29日
0

私の場合は、ヘッダーファイルに接続されているitemGroup cppファイルの.vcxprojにこの行を追加すると、次のようになります。

<ClCompile Include="file.cpp" />