일반 C 내보내기를 원하면 C ++가 아닌 C 프로젝트를 사용하십시오. C ++ DLL은 모든 C ++ ism (네임 스페이스 등)에 대해 이름 변경에 의존합니다. C / C ++-> Advanced 아래의 프로젝트 설정으로 이동하여 코드를 C로 컴파일 할 수 있습니다. 컴파일러 스위치 / TP 및 / TC에 해당하는 "Compile As"옵션이 있습니다.
여전히 C ++를 사용하여 lib의 내부를 작성하고 싶지만 일부 함수를 C ++ 외부에서 사용하기 위해 얽 히지 않은 상태로 내보내려면 아래 두 번째 섹션을 참조하십시오.
VC ++에서 DLL 라이브러리 내보내기 / 가져 오기
정말로 원하는 것은 DLL 프로젝트의 모든 소스 파일에 포함될 헤더에 조건부 매크로를 정의하는 것입니다.
#ifdef LIBRARY_EXPORTS
# define LIBRARY_API __declspec(dllexport)
#else
# define LIBRARY_API __declspec(dllimport)
#endif
그런 다음 내보내려는 함수에서 다음을 사용하십시오 LIBRARY_API
.
LIBRARY_API int GetCoolInteger();
라이브러리 빌드 프로젝트에서 정의를 생성하면 LIBRARY_EXPORTS
DLL 빌드를 위해 함수를 내보낼 수 있습니다.
이후 LIBRARY_EXPORTS
해당 프로젝트가 기능을 대신 가져옵니다 모두의 라이브러리의 헤더 파일을 포함하는 DLL을 소모 프로젝트에 정의되지 않습니다.
라이브러리가 교차 플랫폼 인 경우 Windows가 아닌 경우 LIBRARY_API를 아무것도 정의하지 않을 수 있습니다.
#ifdef _WIN32
# ifdef LIBRARY_EXPORTS
# define LIBRARY_API __declspec(dllexport)
# else
# define LIBRARY_API __declspec(dllimport)
# endif
#elif
# define LIBRARY_API
#endif
dllexport / dllimport를 사용할 때 DEF 파일을 사용할 필요가 없습니다. DEF 파일을 사용하는 경우 dllexport / dllimport를 사용할 필요가 없습니다. 두 가지 방법은 동일한 작업을 다른 방식으로 수행하므로 dllexport / dllimport가 두 가지 중에서 권장되는 방법이라고 생각합니다.
LoadLibrary / PInvoke 용 C ++ DLL에서 얽 히지 않은 함수 내보내기
LoadLibrary 및 GetProcAddress를 사용하거나 다른 언어 (예 : .NET의 PInvoke 또는 Python / R의 FFI 등)에서 가져 오기 위해 필요한 경우 다음을 사용할 수 있습니다. extern "C"
dllexport와 함께 인라인을 하여 C ++ 컴파일러에 이름을 조작하지 않도록 지시 할 수 있습니다. 그리고 dllimport 대신 GetProcAddress를 사용하고 있으므로 위에서 ifdef 댄스를 수행 할 필요가 없습니다. 간단한 dllexport 만 있으면됩니다.
코드:
#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport)
EXTERN_DLL_EXPORT int getEngineVersion() {
return 1;
}
EXTERN_DLL_EXPORT void registerPlugin(Kernel &K) {
K.getGraphicsServer().addGraphicsDriver(
auto_ptr<GraphicsServer::GraphicsDriver>(new OpenGLGraphicsDriver())
);
}
다음은 Dumpbin / exports를 사용한 내보내기의 모습입니다.
Dump of file opengl_plugin.dll
File Type: DLL
Section contains the following exports for opengl_plugin.dll
00000000 characteristics
49866068 time date stamp Sun Feb 01 19:54:32 2009
0.00 version
1 ordinal base
2 number of functions
2 number of names
ordinal hint RVA name
1 0 0001110E getEngineVersion = @ILT+265(_getEngineVersion)
2 1 00011028 registerPlugin = @ILT+35(_registerPlugin)
따라서이 코드는 잘 작동합니다.
m_hDLL = ::LoadLibrary(T"opengl_plugin.dll");
m_pfnGetEngineVersion = reinterpret_cast<fnGetEngineVersion *>(
::GetProcAddress(m_hDLL, "getEngineVersion")
);
m_pfnRegisterPlugin = reinterpret_cast<fnRegisterPlugin *>(
::GetProcAddress(m_hDLL, "registerPlugin")
);
extern C
함수의 매개 변수 유형을 설명하는 장식은 제거하지만 함수의 호출 규칙을 설명하는 장식은 제거하지 않습니다. b) 장식을 모두 제거 하려면 DEF 파일에 (장식되지 않은) 이름을 지정해야합니다.