문제

레거시 Visual C++ 6 앱 수정 중에 막혔습니다.C++ DLL 소스에 내가 넣은

extern "C" _declspec(dllexport) char* MyNewVariable = 0;

결과적으로 MyNewVariable이 내보내기 테이블에 표시됩니다(멋지게 장식되지 않음)(dumpbin /exports blah.dll에 표시된 대로).그러나 C 소스 파일에서 액세스할 수 있도록 변수를 선언하는 방법을 알 수 없습니다.나는 다양한 것을 시도했다.

_declspec(dllimport) char* MyNewVariable;

하지만 그러면 링커 오류가 발생합니다.

해결되지 않은 외부 기호 "__declspec(dllimport) char * MyNewVariable" (__imp_?MyNewVariable@@3PADA)

extern "C" _declspec(dllimport) char* MyNewVariable;

Tony가 제안한 대로(그리고 이전에 시도한 대로) 다른 예상 장식이 생성되지만 여전히 제거되지 않았습니다.

해결되지 않은 외부 기호 __imp__MyNewVariable

C 앱에서 C++ DLL 변수에 액세스할 수 있도록 선언을 어떻게 작성합니까?


대답

botismarius와 다른 사람들(모두에게 많은 감사를 드립니다)이 확인한 것처럼 DLL의 .lib와 연결해야 했습니다.이름이 손상되는 것을 방지하려면 데코레이터 없이 이름을 선언해야 했습니다(C 소스에서). 이는 .lib 파일을 사용해야 함을 의미합니다.

도움이 되었습니까?

해결책

DLL을 컴파일한 후 생성된 lib에 대해 링크해야 합니다.프로젝트의 링커 옵션에서 다음을 추가해야 합니다. .lib 파일.그리고 그렇습니다. 변수를 다음과 같이 선언해야 합니다.

extern "C" { declspec(dllimport) char MyNewVariable; }

다른 팁

extern "C"는 장식을 제거하는 방법입니다. 다음을 사용하면 작동합니다.

extern "C" declspec(dllimport) char MyNewVariable;

또는 C++ 또는 C에서 사용할 수 있는 헤더를 원하는 경우(/TC 스위치 사용)

#ifdef __cplusplus
extern "C" {
#endif
declspec(dllimport) char MyNewVariable;
#ifdef __cplusplus
}
#endif

물론 내보내기를 수행하는 dll에 의해 생성된 가져오기 라이브러리와 연결하세요.

누가 보티스마리우스를 다운모드했는지는 잘 모르겠습니다. 왜냐하면 그가 옳기 때문입니다.그 이유는 생성된 .lib가 외부 변수/함수를 쉽게 선언할 수 있게 해주는 가져오기 라이브러리이기 때문입니다. __declspec(dllimport) 그냥 사용하세요.가져오기 라이브러리는 필요한 작업을 단순히 자동화합니다. LoadLibrary() 그리고 GetProcAddress() 전화.이것이 없으면 수동으로 호출해야 합니다.

둘 다 맞습니다.오류 메시지가 설명하는 사실 __imp_?MyNewVariable@@3PADA 장식된 이름을 찾고 있다는 의미이므로 외부 "C"가 필요합니다.그러나 가져오기 라이브러리와의 연결은 또한 그렇지 않으면 다른 링크 오류가 발생합니다.

@그레임:당신 말이 맞아요.OP가 사용하는 "C" 컴파일러는 C99 표준을 적용하지 않고 C++로 컴파일하여 이름을 엉망으로 만드는 것 같습니다.진정한 C 컴파일러는 "C" 부분을 이해하지 못합니다. extern "C" 예어.

에서 DLL 소스 코드 .lib 파일이 수출 상징물:

extern "C" _declspec(dllexport) char* MyNewVariable = 0;

c 클라이언트는 머리글 이 선언을 사용하면 클라이언트 코드가 수입 상징물:

extern "C" _declspec(dllimport) char* MyNewVariable;

이 헤더는 dll 소스 코드에 #include가 포함된 경우 컴파일 오류를 발생시키므로 일반적으로 내보낸 기능과 클라이언트에서만 사용되는 내보내기 헤더에 배치됩니다.

필요한 경우 다음과 같이 어디에든 포함될 수 있는 "범용" 헤더를 만들 수도 있습니다.

#ifdef __cplusplus
extern "C" {
#endif
#ifdef dll_source_file
#define EXPORTED declspec(dllexport) 
#else
#define EXPORTED declspec(dllimport) 
#endif dll_source_file
#ifdef __cplusplus
}
#endif

EXPORTED char* MyNewVariable;

그러면 dll 소스 코드는 다음과 같습니다.

#define dll_source_code 
#include "universal_header.h"

EXPORTED char* MyNewVariable = 0;

클라이언트는 다음과 같습니다.

#include "universal_header.h"
...
MyNewVariable = "Hello, world";

이 작업을 많이 수행하면 상단의 몬스터 #ifdef가 import_magic.h에 들어갈 수 있고 universal_header.h는 다음과 같이 됩니다.

#include "export_magic.h"

EXPORTED char *MyNewVariable;

저는 Windows에서 프로그래밍할 때 _declspec(dllimport)를 사용한 적이 없습니다.간단하게 선언할 수 있어야 합니다.

extern "C" char* MyNewVariable;

DLL이 컴파일될 때 생성된 .libb에 대한 링크입니다.

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