문제

C ++의 관리되지 않은 DLL에 대한 많은 튜토리얼/기사를 읽었습니다. 그러나 내 삶을 위해, 나는 개념을 파악할 수없는 것 같다. 헤더 파일이 필요한지 여부, 내보내는 방법, .lib 파일이 필요한지 여부에 대한 의견 불일치로 쉽게 혼란스러워합니다.

그래서, 내가 그렇게 함수 만 있다고 가정 해 봅시다.

public int calculateSquare(int num)
{
    return num*num;
}

실제 코드를 무시하면이 간단한 기능 자체로 전화 할 수있는 DLL로 무엇을 만들려면 무엇이 필요합니까? __dllexport 또는 첫 번째 줄에 무엇이든지 추가합니까, 아니면 헤더가 필요합니까? 나는이 모든 것에 당황했다.

도움이 되었습니까?

해결책

C ++ 컴파일러에는 헤더 파일이 표시되지 않으며, 전처리기가 완료된 후에는 하나의 큰 소스 파일 (컴파일 장치라고도 함)이 있습니다. 따라서이 기능을 DLL에서 내보내기 위해 헤더가 필요하지 않습니다. 필요한 것은 DLL의 함수를 컴파일하고 클라이언트 코드에서 가져 오는 기능을 내보내는 조건부 편집입니다.

일반적으로 이것은 매크로와 헤더 파일의 조합으로 수행됩니다. MyImportExport라는 매크로를 생성하고 거시적 조건 문을 사용하여 DLL의 __declSpec (dllexport)와 클라이언트 코드에서 __declspec (dllimport)처럼 작동합니다.

파일 myimportexport.h에서

#ifdef SOME_CONDITION
#define MYIMPORTEXPORT __declspec( dllexport )
#else
#define MYIMPORTEXPORT __declspec( dllimport )
#endif

myheader.h 파일에서

#include <MyImportExport.h>

MYIMPORTEXPORT public int calculateSquare(int num)
{
    return num*num;
}

dll .cpp 파일에서

#define SOME_CONDITION

#include <MyHeader.h>

클라이언트 코드 .CPP 파일에서

#include <MyHeader.h>

물론 당신은 또한 당신이 당신이 /dll 옵션.

빌드 프로세스는 또한 .lib 파일을 만들 것입니다. 이것은이 경우 스터브라고하는 정적 LIB입니다.이 경우 클라이언트 코드는 실제 정적 LIB에 연결되는 것처럼 링크해야합니다. 자동으로 클라이언트 코드가 실행될 때 DLL이로드됩니다. 물론 DLL은 조회 메커니즘을 통해 OS에서 찾아야합니다. 즉, DLL을 어디서나 특정 위치에 넣을 수는 없습니다. 여기 그것에 더 가깝습니다.

DLL에서 올바른 기능을 내보내는 지 여부와 클라이언트 코드가 올바르게 가져 오는지 여부를 확인하는 매우 편리한 도구 덤프 빈. 각각 /내보내기 및 /수입으로 실행하십시오.

다른 팁

QBZIZ의 대답은 충분합니다. 보다 C ++에서 관리되지 않은 DLL

완료하려면 : C ++에서 기호를 사용해야하는 경우 컴파일러에 존재하고 종종 프로토 타입을 알려야합니다..

다른 언어에서는 컴파일러가 라이브러리를 자체적으로 탐색하고 기호를 찾습니다. et voilà.

C ++에서는 컴파일러를 알려야합니다.

C/C ++ 헤더를 책 테이블로보십시오.

가장 좋은 방법은 필요한 코드를 공통 장소에 넣는 것입니다. 원하는 경우 "인터페이스". 일반적으로 헤더라고 불리는 헤더 파일에서 수행됩니다. 일반적으로 독립 소스 파일이 아니기 때문입니다. 헤더는 목표를 포함 해야하는 파일 일뿐입니다 (즉, 전처리 서가 사본/붙여 넣기)를 실제 소스 파일에 넣습니다.

물질에서는 두 번 기호 (함수, 클래스, 무엇이든)를 선언 해야하는 것 같습니다. 다른 언어와 비교할 때 거의 이단입니다.

책, 요약 테이블 또는 색인이있는 책으로보아야합니다. 테이블에는 모든 장이 있습니다. 본문에는 장과 그 내용이 있습니다.

그리고 때로는 챕터 목록이 있다는 것이 기쁩니다.

C ++에서는 이것이 헤더입니다.

DLL은 어떻습니까?

따라서 DLL 문제로 돌아 가기 : DLL의 목표는 코드가 사용할 기호를 내보내는 것입니다.

따라서 C ++ 방식으로 컴파일시 코드를 내보내고 (예 : Windows에서 __declSpec을 사용하고) 내보내기 테이블을 "게시"해야합니다 (즉, 내보내기 선언이 포함 된 "공개"헤더가 있습니다). .

함수 내보내기 체크리스트 :

  • 전화 컨벤션이 발신자에게 적합합니까? (이것은 매개 변수와 결과가 통과되는 방법과 스택 청소를 담당하는 사람을 결정합니다). 당신은 당신의 전화 컨벤션을 명시 적으로 언급해야합니다.
  • 어떤 이름에서 기호가 내보낼까요? C ++는 일반적으로 다른 과부하를 구별하기 위해 기호의 이름을 장식 ( "Mangle")해야합니다.
  • 링커에 기능을 DLL 내보내기로 보이도록 지시하십시오.

MSVC에서 :

  • __stdcall (Pascal Calling Convention)는 수출 된 상징에 대한 전형적인 통화 협약입니다. 대부분의 고객이 지원합니다.
  • extern "c"는 이름 mangling없이 기호 C 스타일을 내보낼 수 있습니다.
  • 사용 __declspec(dllexport) 내보낼 기호를 표시하거나 내보낼 기호가 나열된 별도의 .def 파일을 연결하려면. .def 파일을 사용하면 서수 만 (이름이 아닌)로 내보내고 내보내는 기호의 이름을 변경할 수도 있습니다.

어느 중 하나를 사용하여 기능을 내보내야합니다__declspec( dllexport ) 또는 모듈 정의 파일 (.def)에 함수를 추가합니다. 그런 다음 프로젝트를 DLL로 컴파일하십시오.

클라이언트 측에는 두 가지 옵션이 있습니다. DLL을 컴파일 할 때 생성되는 가져 오기 라이브러리 (.lib)를 사용하십시오. 이 라이브러리와 클라이언트 프로젝트와 연결하면 DLL에서 내보낸 기능에 액세스 할 수 있습니다. 컴파일러는 기능의 서명을 알아야하므로 int를 반환하고 int를 가져 오는 헤더 파일이 필요합니다. 요약하려면 가져 오기 라이브러리 (.lib) 및 기능의 헤더가 포함 된 헤더 파일과 링크해야합니다.

또 다른 방법은 DLL을 동적으로 사용하는 것입니다 WinAPI 전화 LoadLibrary 그리고 GetProcAddress 함수에 대한 포인터를 얻으려면. 기능에 대한 포인터에는 올바른 유형이 있어야하므로 컴파일러가 올바른 매개 변수를 줄 수 있고 올바른 호출 규칙이 사용됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top