web-dev-qa-db-ja.com

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

このエラーが出ますが、修正方法がわかりません。

私はVisual Studio 2013を使用しています。ソリューション名を作成しました。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が出ます:未解決の外部シンボル。 functionmultipleの実装が欠けていることを私は知っています。 function.cppファイルを削除しようとしましたが、宣言を定義に置き換えて実行しました。しかし、宣言と定義の両方を同じファイルに書くことはお勧めできません。それをせずにどうすればこのエラーを修正できますか?ファイルunittest.cppの#include "../MyProjectTest/function.cpp"に置き換えるべきですか? (私は英語があまり得意ではありません。ありがとう)

82
phibao37

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

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

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

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

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

65
kevintodisco

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

34
Niyaz Ivanov

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

13
harrygg

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

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

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

8
cahit beyaz

あなたが(私がしたように)このリンカエラーを得ることができるもう一つの方法は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クラスもexport/importクラスとして宣言する必要がありましたそうでなければ、他のDLLでbook.WordCount()を呼び出すとリンクエラーが発生していました。

5
zar

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

リンカエラーは非常に謎めいていましたが、エラーを読み通すことで欠けていたものを絞り込み、これを解決するためにクラス外の定義を提供しました。

1
Mushy

私がうまくいくのは、ヘッダファイルに接続されているitemGroup cppファイルの.vcxprojにこの行を追加すればうまくいくことです。

<ClCompile Include="file.cpp" />
0
Nejc Galof

これは私に起こったので、私は私の解決策を共有することができると思った。

設定プロパティ - >全般 - で両方のプロジェクトの文字セットを確認してください。 >文字セット

私のUnitTestプロジェクトはデフォルトの文字セットマルチバイトを使用していましたが、私のlibsはUnicode
私の関数はパラメータとしてTCHARを使用していました。私のライブラリでは、結果としてmyTCHARに変換されました )_ wchar _しかし、それは私のUnitTestではchar *でした。パラメータは実際には結局同じではありません。

0
Enyx

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

詳細については、MSDNブログの Visual StudioでのC++ユニットテスト を参照してください。また、 Visual StudioでC/C++のユニットテストを書く 、および をチェックすることもできます。 Visual StudioのC++の場合 、パブリックではないメンバーをテストする必要があり、実際のコードと同じプロジェクトにテストを配置する必要がある場合は後者です。

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

0
user276648