Search
Duplicate

C++/ C++ .h, .lib를 참조하지 않고 DLL 로드

기본적으로 C++에서 C++ DLL을 참조할 때는, 헤더 파일(.h)와 라이브러리 파일(.lib)를 프로젝트 내에서 참조를 해서 빌드하게 되는데, 만일 배포된 DLL이 오로지 DLL 파일만 존재한다면, 해당 DLL을 참조해서 빌드할 수가 없다.
이 경우에는 아예 해당 DLL을 코드 상에서 직접 Load 해서 사용해야 하는데, 이는 다음과 같다. 물론 이 방법을 사용하려면 DLL 내부에 어떤 함수들이 있는지를 알아야 한다.

DLL 로드 및 함수 사용

먼저 로드 하려는 DLL 파일이 다음과 같은 함수를 가졌다고 가정하자.
extern "C" __declspec(dllexport) int add(int a, int b) { return a + b; }
C++
복사
이 add 함수는 2개의 int 파라미터를 받아서 최종적으로 int를 반환하는 함수이다. 이 함수를 먼저 DLL을 사용하려는 프로젝트에서 typedef를 이용하여 다음과 같이 함수 포인터를 선언해 주어야 한다.
추가로 코드 상에서 DLL을 로드 하기 위해 <Windows.h>를 include 해줘야 한다.
#include <Windows.h> typedef int(*DllFuncAdd)(int, int);
C++
복사
다음으로 load 하려는 DLL을 <Windows.h>의 LoadLibrary()를 이용해서 DLL 파일을 HMODULE에 로드한다. —로드 하려는 DLL의 이름이 MyDLL.이라고 하자.
HMODULE hMyDLL = LoadLibrary(L"MyDLL.dll"); // MyDLL.dll 파일이 있는 경로 if (!hMyDLL) { std::cerr << "Unable to load MyDLL.dll" << std::endl; return 1; }
C++
복사
다음으로 실제 사용하려는 함수를 GetProcAddress()을 이용해서 불러오고 reinterpret_cast()을 이용해서 앞서 선언했던 함수 포인터 형태로 변환한다.
// DllFuncAdd는 위에서 선언해 둔 함수 포인터의 타입 DllFuncAdd dllFuncAdd = reinterpret_cast<DllFuncAdd>(GetProcAddress(hMyDLL, "add")); if (!dllFuncAdd) { std::cerr << "Unable to find the 'add' function in MyDLL.dll" << std::endl; FreeLibrary(hMyDLL); return 1; }
C++
복사
로드한 DLL 함수를 실제 사용한다.
int result = dllFuncAdd(3, 4); std::cout << "3 + 4 = " << result << std::endl; // 3 + 4 = 7
C++
복사
사용이 끝난 DLL은 FreeLibrary로 제거한다.
FreeLibrary(hMyDLL);
C++
복사

예제

기본적으로는 위와 같은 흐름으로 사용하면 되지만, 만약 코드 상에서 부르려는 DLL과 함수를 코드 상에서 여러 번 사용한다면, DLL과 함수를 전역으로 관리해서 사용하는 것이 좋을 것이다.
아래는 프로그램 시작시 DLL을 로드하고 —이때 사용하려는 함수까지 한 번에 불러옴— 프로그램 종료시 DLL을 해제하는 예제 코드이다.
#include <iostream> #include <Windows.h> typedef int(*DllFuncAdd)(int, int); HMODULE hMyDLL = nullptr; DllFuncAdd dllFuncAdd = nullptr; bool loadDLL() { hMyDLL = LoadLibrary(L"MyDLL.dll"); if (!hMyDLL) { std::cerr << "Unable to load MyDLL.dll" << std::endl; return false; } dllFuncAdd = reinterpret_cast<DllFuncAdd>(GetProcAddress(hMyDLL, "add")); if (!dllFuncAdd) { std::cerr << "Unable to find the 'add' function in MyDLL.dll" << std::endl; FreeLibrary(hMyDLL); return false; } return true; } void freeDLL() { if (hMyDLL) { FreeLibrary(hMyDLL); hMyDLL = nullptr; } } int main() { if (!loadDLL()) { return 1; } std::cout << "3 + 4 = " << dllFuncAdd(3, 4) << std::endl; freeDLL(); return 0; }
C++
복사