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


99

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

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

構造

- 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 ソリューション:ソリューションに追加すると 、場所が現在開いているソリューションのパスに自動的に切り替わります。これは、ソリューションのフォルダー構造です。

フォルダー構造

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



6
注意してくださいWindows環境では、静的ライブラリには.LIBファイル拡張子があります。物事を複雑にする...ダイナミックリンクライブラリ(つまり*.DLL)には、ファイル拡張子も付いたインポートライブラリが付随している場合があり.LIBます。このインポートライブラリには、が提供するすべての便利な機能がリストされてい*.DLLます。詳細については、次を参照してください。リンカーの初心者向けガイド
プレサッコ

4
なぜ彼は注意する必要がありますか?
マーシャルクラフト

回答:


80

1つのオプションは含まれるようになりfunction.cpp、あなたの中UnitTest1のプロジェクトが、それは最も理想的なソリューション構造ではないかもしれません。問題の簡単な答えは、UnitTest1プロジェクトをビルドするとき、コンパイラとリンカーには存在するアイデアがなくfunction.cpp、の定義を含むリンクするものもないということですmultiple。これを修正する方法は、リンクライブラリを利用することです。

単体テストは別のプロジェクトにあるため、そのプロジェクトをスタンドアロンの単体テストプログラムにすることを想定しています。テストしている関数が別のプロジェクトにある場合、そのプロジェクトを動的または静的にリンクされたライブラリーにビルドできます。静的ライブラリはビルド時に他のプログラムに.libリンクされ、拡張子が付き.dllます。動的ライブラリは実行時にリンクされ、拡張子が付きます。私の回答では、静的ライブラリを使用します。

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

あなたにはUnitTest1このプロジェクトには、そのプロパティに行くことができ、カテゴリの追加ライブラリディレクトリにあるリンカ]タブの下で、これにパスを追加しますMyProjectTest構築しますが。次に、[リンカー-入力]タブの[追加の依存関係]に、静的ライブラリの名前を追加しますMyProjectTest.lib

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


「リンカー->入力タブ」で、静的ライブラリの「(OutDir)」、つまり「$(OutDir)MyProjectTest.lib」のプレフィックスを付ける必要がありましたが、「MyProject」と「MyTestProject」の両方の場所は同じルートフォルダーにありました。
Pabitra Dash 2018

13
したがって、単体テストを実行するたびに、テスト対象プロジェクトを静的ライブラリに変換する必要があります。また、プログラムを実際に実行するたびに、プログラムを実行可能ファイルに変換して戻すには、どうすればよいのでしょうか。
A. Smoliak

1
MyProjectTestがdllの場合、テストできますか?インポートライブラリを追加するか、objファイルを追加する必要がありますか?
2019

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

39

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


4
実際のファイルはProjDirにコピーまたは移動されないことに注意してください。
Laurie Stearn 2018年

このメソッドは、c ++ libをCLIプロジェクトに追加しようとして発生した同様の問題を解決しました。
Deshan

17

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


1
MyProjectTestがdllである場合はどうですか?設定できますか?
2019

多くのobjファイルがある場合。この* .objのようなものを追加できますか?あなたの解決策は私とうまくいきましたが、私はすべての新しいobjファイルを手動で追加したくありません。
2019

10

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

  1. ソリューションエクスプローラーでプロジェクトを右クリックします。
  2. [追加] => [参照]をクリックします...
  3. [新しい参照の追加]ボタンをクリックします
  4. このプロジェクトが依存するプロジェクトのチェックボックスをオンにします
  5. OKをクリックします

依存関係を設定するとはどういう意味ですか?参照を追加しましたが、まだ不満があります。devblogs.microsoft.com/cppblog/cpp-testing-in-visual-studioはそれで十分だと提案しました。
tschumann

8

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


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()ました。


2

これは私に起こったので、私は自分の解決策を共有することを考えました。

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

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


1

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

リンカエラーは非常に不可解ですが、エラーを読み通して欠落しているものを絞り込み、クラス外の定義を提供してこれを明らかにしました。


一部のケースでの問題は、クラス定義を含むヘッダーがすべて適切に参照/インクルードされているが、対応するcppがリンカーで使用できない場合があることです。チェックする最良の方法は、ソリューションエクスプローラーでプロジェクトの外部依存関係をフリックすることです。ただし、VSがエラーに関する何らかのファイルの存在/包含に関する警告を発行することは有益です。
Laurie Stearn 2018年

1

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


0

私は作品のために、私は怒鳴るこの行を追加した場合.vcxprojにはitemGroup、ヘッダファイルに接続されているCPPファイル、。

<ClCompile Include="file.cpp" />

0

Visual Studio 2017でパブリックメンバーをテストする場合は、実際のプロジェクトとテストプロジェクトを同じソリューションに配置し、テストプロジェクトに実際のプロジェクトへの参照を追加します。

詳細については、MSDNブログの「Visual StudioでのC ++ユニットテスト」を参照してください。Visual StudioでC / C ++の書き込みユニットテストを確認することや、Visual StudioでC ++ のMicrosoftユニットテストフレームワークを使用することもできます。後者は、非パブリックメンバーをテストする必要があり、同じプロジェクトにテストを配置する必要がある場合です。あなたの本当のコードとして。

テストするものは、を使用してエクスポートする必要があることに注意してください__declspec(dllexport)。詳細については、__ declspec(dllexport)使用したDLLからのエクスポートを参照してください。

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