2012-05-02 3 views
5

제목에 따라 C를 사용하여 DLL을 만들고 C++ 프로젝트에서 링크하려고합니다. 나는 인터넷에서 다른 튜토리얼을 읽고 따라 갔지만 매번 누락 된 것이 있으며 무엇을 이해하지 못한다.C에서 DLL을 만들고 C++ 프로젝트에서 연결

가 여기에 내가 단계적으로, 무슨 짓을했는지 :

난 후, testlib라는 이름의 새로운 Win32에서 프로젝트를 생성 마법사에서, 나는 "DLL"과 "빈 프로젝트"를 선택했다.

추가 헤더 :

//testlib.h 

#include <stdio.h> 

__declspec(dllexport) void hello(); 

추가 된 소스; 나는 그것이 C 소스가되고 싶어요 때문에 나는 그렇게

//testlib.c 

#include "testlib.h" 

void hello() { 
    printf("DLL hello() called\n"); 
} 

빌드가 succeded, 내가 simplly이 .c에서 .cpp 파일의 이름을 변경해야 읽어 보시기 바랍니다.

이제 다른 프로젝트에서 유용한 DLL을 사용하고 싶습니다.

다음 : 새 프로젝트 (testlibUse). 이번에는 "Empty project"를 선택했습니다. 내가 속성 -에 testlib.dll> VC++ 디렉토리 -> 실행 디렉토리에있는 폴더의 경로를 추가

  • :
    헤더를 추가 할 필요가 없습니다, 단지 CPP 소스 그리고

    //main.cpp 
    #include <testlib.h> 
    
    int main() { 
        hello(); 
    } 
    

    을 생성

  • 폴더에 경로를 추가했습니다 (등록 정보 -> VC++ 디렉토리 -> 디렉토리 포함) testlib.h

  • ,
  • 나는 testlib.lib 속성 -에 (포함 확장)> 링커 -> 입력 -> 내가 만들려고 추가 종속성

의 경로를 추가하지만 난 링커 오류 가지고 :

LINK : C:\path\testlibUse\Debug\testlibUse.exe not found or not built by the last incremental link; performing full link
main.obj : error LNK2019: unresolved external symbol "void __cdecl hello(void)" ([email protected]@YAXXZ) referenced in function _main
C:\path\testlibUse\Debug\testlibUse.exe : fatal error LNK1120: 1 unresolved externals

testlib으로 돌아 가면 의 이름을 testlib.cpp으로 변경하고 dll을 다시 작성하면 testlibUse을 빌드 할 수 있지만 런타임에 "dll을 찾을 수 없음"오류가 발생합니다.

"Release"(필요한 경우 경로 변경)에서 두 프로젝트의 구성을 변경하려고했지만 아무 것도 변경되지 않았습니다.

오랫동안 미안하지만 나는 내가 한 일을 정확히 적어 두는 것이 필요하다고 생각합니다.

제안 사항?

게다가 Qt 프로젝트에서 내 dll을 사용하려면 변경해야 할 구성 매개 변수가 있습니까?

답변

9

당신은 몇 가지 문제가 있습니다

  1. 때 DLL 컴파일 만 가져 반출 등의 기능을 표시해야합니다 헤더 파일 라이브러리 사용자가 컴파일 할 때.
  2. 이름이 DLL은 실행 파일의 라이브러리 검색 경로에없는 난도질
  3. 을하지 않도록 C++로 컴파일 될 때 헤더 파일은 extern "C" 블록에서 함수 선언을 포장한다, 그래서 그것을 찾을 수 없습니다 런타임에.

(1) 수정 (2),이 같은 헤더를 다시 작성하려면

#ifdef __cplusplus 
extern "C" { 
#endif 

// Assume this symbol is only defined by your DLL project, so we can either 
// export or import the symbols as appropriate 
#if COMPILING_MY_TEST_DLL 
#define TESTLIB_EXPORT __declspec(dllexport) 
#else 
#define TESTLIB_EXPORT __declspec(dllimport) 
#endif 

TESTLIB_EXPORT void hello(); 
// ... more function declarations, marked with TESTLIB_EXPORT 

#ifdef __cplusplus 
} 
#endif 

(3) 귀하의 실행 파일과 같은 폴더에 DLL을 복사 해결하려면. 설정중인 "실행 디렉터리"설정은 DLL 검색에 영향을 미치지 않습니다. DLL을 검색하는 방법에 대한 자세한 설명은 MSDN을 참조하십시오. 가장 좋은 해결책은 DLL을 실행 파일이있는 디렉토리에 복사하는 것입니다. 이 작업을 수동으로 수행하거나이 작업을 수행하는 사후 빌드 단계를 프로젝트에 추가 할 수 있습니다.

1

컴파일러가 mangle이 아닌지 확인해야하는 것처럼 보입니다. cpp 빌드의 심볼 이름입니다. testlib의 정의에 extern "C"을 추가 할 수 있어야합니다.시간 :

#ifdef __cplusplus 
extern "C" 
#endif 
__declspec(dllexport) void hello(); 
+0

빌드가 성공적이지만 런타임에 "dll not found"오류가 발생합니다 ... 등록 정보 -> VC++ 디렉토리 -> 실행 가능 디렉토리에서 dll에 경로를 추가하는 것으로 충분하지 않습니까? – Saphrosit

+0

@Saphrosit : 아니요, 아는 한, 앱 실행에 영향을 미치지 않습니다. 해당 속성 페이지에 대한 설명을 읽으십시오. 프로젝트를 빌드하는 동안 바이너리 찾기에 영향을줍니다. 런타임에 DLL을 (예 : PATH 환경 변수를 통해) 찾을 수 있어야합니다. –

2

당신은 extern "C"은 포함한다 :

+0

빌드 성공했지만 런타임에 "dll을 찾을 수 없음"오류가 발생했습니다 ... Properties-> VC++ directories-> Executable 디렉토리에서 dll에 경로를 추가하는 것으로 충분하지 않습니까? – Saphrosit

1

다음은 C++으로 포함 할 수 귀하의 C 헤더 파일을위한 방법입니다. 전 처리기 설정에서만 TESTLIB_EXPORTS을 설정해야합니다. 이 헤더를 사용하여 DLL을 사용하는 프로젝트에서 헤더는 내보내기 대신 함수를 가져 오기로 선언합니다.

__cplusplus 가드 C 이름 장식 대신 C++ 이름 장식을 사용하여 기능을 가져올 수있는 컴파일러를 알려줍니다.

관련 문제