2010-01-16 7 views
1

암시 적 링크로 DLL을 연구하기 시작했습니다. 나는 그것이 어떻게 작동하는지 완전히 이해하지 못한다. 내가 틀린 곳에서 나를 교정 해주세요.암시 적 링크 DLL 질문

MyLib.h 지금까지 내가이 DLL의 헤더 인 이해

#ifdef MYLIBAPI 

#else 


#define MYLIBAPI extern "C" __declspec(dllimport) 

#endif 


MYLIBAPI int g_nResult; 

MYLIBAPI int Add(int nLeft, int nRight); 

: 나는 다음 코드 (3 모듈)을 컴파일하는 데 실패했습니다. #define MYLIBAPI extern "C" __declspec(dllimport)은 여기에 헌신 된 .cpp 파일에 설명되고 DLL에 포함될 일부 함수/변수를 선언한다는 것을 의미합니다.

#include <windows.h> 

#define MYLIBAPI extern "C" __declspec(dllexport) 

#include "MyLib.h" 

int g_nResult; 
int Add(int nLeft, int nRight) { 
    g_nResult = nLeft + nRight; 
    return(g_nResult); 
} 

MyLibFile1.cpp 그래서, 이것은 분명히 우리의 기능이 구현되어있는 파일입니다. 이것은 DLL의 일부입니다.

MyExeFile1.cpp

#include <windows.h> 
#include <strsafe.h> 
#include <stdlib.h> 

#include "MyLib.h" 

int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) { 

    int nLeft = 10, nRight = 25; 

    TCHAR sz[100]; 
    StringCchPrintf(sz, _countof(sz), TEXT("%d + %d = %d"), 
     nLeft, nRight, Add(nLeft, nRight)); 
    MessageBox(NULL, sz, TEXT("Calculation"), MB_OK); 

    StringCchPrintf(sz, _countof(sz), 
     TEXT("The result from the last Add is: %d"), g_nResult); 
    MessageBox(NULL, sz, TEXT("Last Result"), MB_OK); 
    return(0); 
} 

그래서, 이것은 우리가 라이브러리에서 함수를 사용하는 실행 파일입니다. 모든 것이 작동하지 않습니다. 이 모든 것을 하나의 디렉토리에 넣고 한 번에 컴파일하려고했습니다. 첫 번째 두 모듈 (성공적으로)에서 DLL을 먼저 컴파일 한 다음 실행 파일을 컴파일하여 (헤더 파일의 경로를 변경) 시도했습니다.

오류 LNK2019 : 그러나 그것은이 오류가 두 번 결과 확인되지 않은 외부 기호 _WinMain을 기능 ___tmainCRTStartup 비주얼 스튜디오 2008 \

프로젝트 \ \ MyExeFile1 \ 디버그 \ MyExeFile1.exe에서 참조 16 @ : 치명적인 오류 LNK1120 : 1 해결되지 않은 외부

올바른 방법은 무엇입니까? 코드에서 무엇을 변경해야하며 VS2008을 사용하여 코드를 컴파일해야합니까? 감사합니다. .

답변

1

#include <tchar.h> 링커 오류를 해결합니다.

헤더 파일은 다음과 같아야합니다

#ifdef BUILDING_DLL 
# define MYLIBAPI extern "C" __declspec(dllexport) 
#else 
# define MYLIBAPI extern "C" __declspec(dllimport) 
#endif 

MYLIBAPI int __stdcall Add(int nLeft, int nRight); 

마우스 오른쪽 단추로 클릭하고 "BUILDING_DLL"를 추가, 솔루션 탐색기, 속성, C/C++, 처리기, 처리기 정의에 DLL 프로젝트를. 릴리스 구성에 대해 반복하십시오.

DLL이 Dumpbin.exe/exports를 사용하여 함수를 제대로 내보내는 지 확인할 수 있습니다.

__declspec (dllimport) 선언자는 꼭 필요한 것은 아니지만보다 효율적으로 만듭니다. __stdcall 특성은 필요하지 않지만 DLL을 호출하는 것을 지원하는 언어로 DLL을 쓸 수 있습니다.

+0

고마워 .. 나는 어떻게되는지 잘 이해하지 못합니다. 선처리기 정의를 추가하면 언제 BUILDING_DLL이 정의되고 언제 정의되지 않습니까? 그 목적은 무엇입니까? 나는 이런 식으로 생각 : DLL이 컴파일되지 않은 동안, BUILDING_DLL 정의되지 않은, 그래서 우리는 DLL에 함수를 가져 오는거야? ... (이제는 dllimport/dllexport 파트를 전혀 이해하지 못한다는 것을 알 수 있습니다) – lhj7362

+1

전 처리기 정의를 추가 할 때 # 정의됩니다. DLL 프로젝트에서 그렇게 했으므로 함수를 내보낼 수 있습니다. 함수가 임포트되는 것을 보장하는 다른 프로젝트에서는 정의되지 않습니다. –

0

MyExeFile1.cpp에서 _tWinMain을 WinMain으로 변경하십시오. 엔트리 포인트가 _tWinMain이 아닌 WinMain이라는 이름을 갖기 때문에 링커가 WinMain을 찾을 수 없다는 불평을합니다.

엔트리 포인트 함수의 이름을 결정하는 프로젝트 설정이 있지만 _tWinMain이 필요한 항목을 잘 모르겠습니다.

편집 이 게시물에 따르면 _tWinMain은 tchar.h를 포함하면 WinMain에 매핑되는 정의입니다. link text

+0

'_tWinMain'은 프로젝트의'_UNICODE' 설정에 따라 확장 된 정의 일 가능성이 큽니다. – Dmitry

+0

와우, 네 말이 맞아. _tWinMain을 WinMain으로 바꾸고 tchar를 separetely로 포함 시켰습니다. 나는 왜 "나는 해결되지 않은 외부"오류가 있었는지 이해하지 못한다. 하지만 어쨌든, 고마워! – lhj7362

0

컴파일도됩니까? 모든 TCHAR 유형 및 정의가 작동하려면 #include <tchar.h>을 사용해야합니까?

+0

다른 오류로 인해 컴파일되지 않습니다. strsafe.h를 포함하는 것으로 충분할 것 같습니다. 편집 : 아마도 _tWinMain에는 tchar이 포함됩니다. – lhj7362

+0

'_tWinMain'은 tchar.h에서 _defined_이며, _char_t를 포함 할 수 없습니다 :) – Dmitry