최우택 님이 쓰신 글 :
: C++builder에서의 DLL함수 사용에 관한 질문입니다.
: installshield Express에서 제품번호를 입력하도록 만들어야 하는데, 사용되는 DLL에서의 예제
: 함수로 다음의 함수들이 들어있더군요.
:
: BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
: {
: return true;
: }
:
: LONG WINAPI ValidateSN( HWND hwnd, LPSTR szSrcDir,
: LPSTR szSupport, LPSTR szSerialNum, LPSTR szDbase )
: {
: ....
: return 1;
: }
:
:
: 기래서... C++빌더에서 똑같이 동일하게 동작하는 DLL을 만드려고 하는데, 어떻게 함수 선언을 해야 하는지 알고 싶습니다. C++빌더에서 DLL만드는 것에 관한 수중의 책은 정보문화사꺼 뿐인데... 이 책의 내용만으로는 감이 잡히지 않습니다. 빌더에서 만든 DLL을 빌더에서 만든 프로그램에서 호출해 사용하는 것은 좀 해봤지만.... 아무래도 그대로 적용하기엔 뭔가 다른거 같더군요. 이래저래 함수 선언들을 뒤집어 볶아대고 조합해 봤지만... 계속 인스톨 프로그램에서는 함수를 찾지 못한다는 메시지를 띄웁니다. 빌더에서의 Dll과 VC의 Dll에서의 함수명 구조가 다르다는 이야기를 듣긴 했는데.. 그런 문제인지... ( 그렇지만 예제를 VC에서 DLL을 컴파일해서 사용하면 잘만 됩니다. 기분나쁘게.. -.-; )
제가 이필호님 홈페이지에 질문했던 내용입니다.
약간 수정해서 올립니다.
참고 : 이필호님 홈
http://home.jiran.com/~xius
--------------------------------------------------------------------------------
File -> New 를 선택하시고, DLL을 선택하세요...
그리고 생성된 파일에 다음과 같은 코딩을 넣어주세요.
extern "C" long __export sum(int a, int b)
{
return (a+b);
}
그리고, 컴파일을 하시면 DLL이 생성되겠죠? 그 DLL을 user.dll 이라고 하면..
그 DLL을 호출하는 프로그램에서..(예를 들어 Unit1.CPP 에서 이 두줄을 선언해 주세요)
long (__stdcall *sum)(int a, int b);
HANDLE dllInstance;
그리고 다음 라인을 실체 호출하는 곳에서 써주면 됩니다.
dllInstance = LoadLibrary("[DLL 전체경로명과 이름]");
---> 이것은 dll 파일을 로드하는것이구요.
if(dllInstance)
{
sum = (long (__stdcall *)(int, int)) GetProcAddress(dllInstance, "_sum");
}
---> 이것은 dll 파일내에 여러가지 함수중에서 특정함수를 가져오는것입니다.
그리고 위의 것은 함수를 사용하기 이전에 실행되어야겠죠.
이후에...
sum() 이란 함수를 쓰시면 됩니다.
좀 설명을 해드리면..
우선..
DLL에 다음과 같이 선언이 되어 있는데..
extern "C" long __export sum(int a, int b)
이것은 long sum(int a, int b) 함수를 C 함수 형식으로 Export한다는 것입니다. 그러면.. Borland 컴파일러가 sum함수를 export하는데, 여기서 주의하실 것이 있습니다. Borland 계열 컴파일러는 함수를 export하면 반드시 "_ (언더바)"가 붙습니다. 그냥 자동으로요...
그러니까.. sum() 함수를 export하면 _sum() 함수가 DLL에 들어 있는거죠..
왜냐구요? 건 저두 잘 몰러~~... ^.^
하여간 그렇습니다...
그럼.. 호출하는 곳에서 이 DLL을 호출해야 하는데, 우선 DLL을 메모리에 가져와야 겠죠?
그것이..
dllInstance = LoadLibrary("[DLL 전체경로명과 이름]");
입니다.
전체 경로명을 써주지 않으면 Windows 시스템이나 현재디렉토리에서 찾으니까.. 아예 시스템에 복사하시고 싶으시면 시스템에 복사하고 DLL명만 써주어도 됩니다.
DLL을 메모리에 로드하면.. DLL안에 있는 함수가 어디에 있는지 찾아야하는데요..그 함수는
sum = (long (__stdcall *)(int, int)) GetProcAddress(dllInstance, "_sum");
입니다.
여기서 앞에 sum 은 sum() 함수 포인터입니다. 즉, DLL의 _sum() 함수의 위치를 읽어서 sum() 함수의 함수 포인터에 넘겨주면.. 다음부터 sum() 함수를 쓰면 DLL안에 있는 _sum()함수가 실행되는 것이죠..
좀 복잡하죠? 해보시면 금방 알것입니다.
위의 함수 선언을 보면..
long (__stdcall *sum)(int a, int b);
이라고 되어 있는데, 이는 long sum()라는 이름의 __stdcall 형식의 함수 포인터입니다.
sum = (long (__stdcall *)(int, int)) GetProcAddress(dllInstance, "_sum");
여기서 (long (__stdcall *)(int, int)) 란 것이 있는데요.. 이것은..
long 형의 리턴형이고 int, int 라는 인자를 가진 __stdcall 형식의 함수 포인터라는 이야기입니다.
으.. 쓰다보니까.. 복잡해 보이는 군요...
자세히 보시면 함수의 형과 인자형이 딱 맞아 떨어지는 것을 확인할수 있을겁니다.
그리고 FreeLibrary(dllInstance) 해주시면 메모리에서 해제됩니다.
DLL과 LIB에 대해서 말씀드리겠습니다.
DLL은 아시는 것과 같이 실행시에 호출하는 라이브러리이구요..
LIB는 컴파일시에 링크되는 라이브러리입니다.
즉, DLL은 실행시에도 필요한 파일이구요.. LIB는 컴파일시에만 있으면 되구. 프로그램이 실행할때는 전혀 필요없는 프로그램입니다.
도움이 되셨으면 합니다.
PS. 제가 말씀드린 방법은 Win32 C 표준 DLL을 불러오는 방법입니다. BCB에서 좀더 편한 방법이 있다면.. 그 방법을 쓰셔도 무방합니다. 제가 말씀드린 방법 한가지만 있는것이 아니기 때문이죠...
그럼...
---------------------------------------------------------------------------------------
여기까지였습니다.