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
조심 A의 윈도우 환경, 정적 라이브러리는이 .LIB파일 확장자를. 복잡하게하기 위해 ... 동적 링크 라이브러리 (예 :) 는 파일 확장자를 가진 가져 오기 라이브러리*.DLL동반 할 수 있습니다 . 이 가져 오기 라이브러리에는 . 자세한 내용은 다음을 참조하십시오. 링커 초보자 가이드.LIB*.DLL
Pressacco

4
왜 조심해야하나요 ??
마샬 공예

답변:


80

한 가지 옵션은 프로젝트 에 포함 function.cpp하는 UnitTest1것이지만 가장 이상적인 솔루션 구조는 아닐 수 있습니다. 문제에 대한 짧은 대답은 UnitTest1프로젝트를 빌드 할 때 컴파일러와 링커가 function.cpp존재 하는지 전혀 모르고 multiple. 이를 수정하는 방법은 링크 라이브러리를 사용하는 것입니다.

단위 테스트가 다른 프로젝트에 있기 때문에 해당 프로젝트를 독립 실행 형 단위 테스트 프로그램으로 만드는 것이 의도라고 가정합니다. 테스트중인 함수가 다른 프로젝트에 있으면 해당 프로젝트를 동적 또는 정적으로 연결된 라이브러리로 빌드 할 수 있습니다. 정적 라이브러리는 빌드시 다른 프로그램에 링크되며 확장자 .lib가이고 동적 라이브러리는 런타임에 링크되며 확장자가 .dll. 내 대답에는 정적 라이브러리를 선호합니다.

프로젝트 속성에서 변경하여 첫 번째 프로그램을 정적 라이브러리로 전환 할 수 있습니다. 프로젝트가 실행 파일 ( .exe) 로 빌드되도록 설정된 일반 탭 아래에 옵션이 있어야합니다 . 이것을로 변경할 수 있습니다 .lib. .lib파일은 같은 장소에 구축 할 것입니다 .exe.

당신의에서 UnitTest1프로젝트, 해당 속성에 갈 수 있고, 카테고리 추가 라이브러리 디렉토리에서 링커 탭 아래에있는에 경로 추가 MyProjectTest빌드를. 그런 다음 링커-입력 탭 아래의 추가 종속성에 대해 정적 라이브러리의 이름을 추가합니다 MyProjectTest.lib.

그러면 프로젝트를 빌드 할 수 있습니다. 이렇게하면 MyProjectTest필요에 따라 빌드 속성을 변경하지 않는 한은 독립 실행 형 실행 프로그램이 아닙니다. 이는 이상적이지 않습니다.


'Linker-> Input Tab'에서 'MyProject'와 'MyTestProject'의 위치는 동일한 루트 폴더에 보관되지만 정적 라이브러리의 경우 '(OutDir)'접두사를 사용해야했습니다. 즉 '$ (OutDir) MyProjectTest.lib'입니다. .
Pabitra Dash

13
따라서 단위 테스트를 실행할 때마다 테스트 대상 프로젝트를 정적 라이브러리로 변환해야하며 실제로 프로그램을 실행할 때마다 다시 실행 파일로 변환해야합니다.이게 어떻게 해결책일까요?
A. Smoliak

1
MyProjectTest가 dll이면 테스트 할 수 있습니까? import lib 만 추가하거나 obj 파일을 추가해야합니까?
aviit

"프로젝트 속성에서 변경하여 첫 번째 프로그램을 정적 라이브러리로 전환 할 수 있습니다. 일반 탭 아래에 프로젝트가 실행 파일 (.exe)로 빌드되도록 설정된 옵션이 있어야합니다.이를 .lib로 변경할 수 있습니다. .lib 파일은 .exe와 같은 위치에 빌드됩니다. "이 작업만으로도 충분했습니다. 나머지는 이미 VS에서 처리했습니다.
Ekrem Solmaz

39

Visual Studio 솔루션 트리에서 'UnitTest1'프로젝트를 마우스 오른쪽 버튼으로 클릭 한 다음 추가-> 기존 항목-> 파일 ../MyProjectTest/function.cpp 선택


4
실제 파일은 ProjDir로 복사되거나 이동되지 않습니다.
Laurie Stearn

이 방법은 CLI 프로젝트에 C ++ lib를 추가하려고 할 때 발생하는 유사한 문제를 해결했습니다.
Deshan

17

내 프로젝트를 독립 실행 형 EXE로 컴파일하기를 원하기 때문에 UnitTest 프로젝트를 function.cpp에서 생성 된 function.obj 파일에 연결하고 작동합니다. 'UnitTest1'프로젝트> 구성 속성> 링커> 입력> 추가 종속성> ".. \ MyProjectTest \ Debug \ function.obj"추가를 마우스 오른쪽 버튼으로 클릭합니다.


1
MyProjectTest가 dll 인 경우는 어떻습니까? 그것을 설정할 수 있습니까?
aviit

obj 파일이 많은 경우. * .obj와 같은 것을 추가 할 수 있습니까? 귀하의 솔루션은 저와 함께 작동했지만 모든 새 obj 파일을 수동으로 추가하고 싶지 않습니다.
aviit

10

방금 Visual Studio 2013에서이 문제가 발생했습니다. 지금은 동일한 솔루션에 두 개의 프로젝트가 있고 종속성을 설정하는 것만으로는 충분하지 않습니다. 그들 사이에 프로젝트 참조를 추가해야합니다. 하기 위해서:

  1. 솔루션 탐색에서 프로젝트를 마우스 오른쪽 단추로 클릭하십시오.
  2. 추가 => 참조 ...를 클릭하십시오.
  3. 새 참조 추가 버튼을 클릭합니다.
  4. 이 프로젝트가 의존하는 프로젝트의 확인란을 선택하십시오.
  5. 확인 클릭

종속성을 설정한다는 것은 무엇을 의미합니까? 참조를 추가했지만 여전히 불만이 있습니다. devblogs.microsoft.com/cppblog/cpp-testing-in-visual-studio 는 충분할 것이라고 제안했습니다.
tschumann

8

.c 파일을 .cpp 파일과 함께 사용하고 있다는 것이 밝혀졌습니다. .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()다른 dll에서 호출 하면 링크 오류가 발생했습니다.


2

이것은 나에게 일어 났으므로 내 솔루션을 다음과 같이 간단하게 공유 할 수 있다고 생각했습니다.

구성 속성 -> 일반 -> 문자 집합 에서 두 프로젝트의 문자 집합을 확인합니다.

내 UnitTest 프로젝트는 기본 문자 세트 멀티 바이트를 사용 하고 내 libs는 Unicode .
내 함수는 TCHAR 를 매개 변수 로 사용했습니다 . 내 LIB의 결과 내 TCHAR는변형WCHAR 그러나 그것은이었다 숯불 * 내 유닛 테스트에서 : 매개 변수가 결국 정말 동일하지 않았기 때문에 기호가 달랐다.


1

난 그냥 그 발견 LNK2019클래스 내부에 선언 된 함수에 대한 정의를 제공 잊는 경우 비주얼 스튜디오 2015에서 컴파일하는 동안 발생합니다.

링커 오류는 매우 모호했지만 오류를 읽어서 누락 된 부분을 좁히고이를 해결하기 위해 클래스 외부에 정의를 제공했습니다.


경우에 따라 문제는 클래스 정의를 포함하는 헤더가 모두 훌륭하게 참조 / 포함되지만 해당 cpp가 링커에서 사용 가능 하지 않을 수 있다는 것 입니다. 확인하는 가장 좋은 방법은 솔루션 탐색기에서 프로젝트 외부 종속성을 살펴 보는 것입니다. VS가 오류에 관한 일종의 파일 존재 / 포함 경고를 발행하는 것이 좋습니다.
Laurie Stearn

1

제 경우에는 속성에서 cpp 파일을 "C / C ++ 컴파일러"로 설정-> 일반 LNK2019 오류를 해결합니다.


0

나는이 라인 울부 짖는 소리를 추가하면 나를 위해, 작동 .vcxprojitemGroup헤더 파일에 연결되어 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.