반응형
동적 라이브러리를 보기 전에 정적 라이브러리를 먼저 살펴 보겠습니다.
O 정적 라이브러리(.LIB)
정적 라이브러리(lib)를 만드는 법은 간단합니다. Visual Studio 2008에서 프로젝트 구성 형식을 정적 라이브러리(.lib)로 만들고 실행을 하면 되기 때문입니다. 이용을 하려면 이 라이브러리(.lib)와 해더 파일(.h)을 이 라이브러리를 이용할 프로젝트에 추가해주면, 이용 또한 쉽습니다.
- 프로젝트에 추가 방법 [첫번째]
1. [프로젝트 - 속성] 선택
2. [링커 - 일반]탭을 선택 후, '추가 라이브러리 디렉터리'에 lib 파일의 경로를 추가.
3. [링커 - 입력]탭을 선택 후, '추가 종속성' 란에 lib 파일을 입력하고, 확인을 누름.
- 프로젝트에 추가 방법 [두번째]
1. main.cpp(App 소스코드를 말함)에서 아래와 같이 입력합니다.
O 동적 라이브러리(.DLL)
동적 라이브러리 또한 정적 라이브러리와 같이 사용이 가능합니다. dll로 프로젝트를 만들고 실행을 하게 되면 dll과 lib 파일이 생성됩니다. 여기서 lib파일에는 dll에 구현된 함수를 찾을 수 있는 정보가 있습니다.(저두 본거라...) 그래서 정적 라이브러리와 같은 방법으로 사용이 가능합니다. 이런 방식을 '암시적 연결'이라고 합니다.
암시적 연결 방법만 있는 것은 아닙니다. 명시적 방법 또한 있습니다. 이 방법은 dll 파일만 있어도 사용 할 수 있습니다. 하지만 C스타일의 함수여야 하는 듯 합니다. 아래를 보시면 아시겠지만 함수의 이름으로 주소를 얻어오기 때문에 C++에서 사용 할 수 있는 오버로딩이 되지 않습니다. 오버로딩이란 함수의 이름은 같지만 매개변수가 다를 경우 다른 함수로 간주 하는 것을 말합니다.
한번 코드로 정리 해보겠습니다. 첫번째는 헤더와 lib파일을 이용해서 dll을 사용하는 방법입니다.
- DLL 소스코드
- App 소스코드1 (.h + .lib 이용하여 dll 함수 호출)
- App 소스코드2 (WinAPI를 이용하여 dll 함수 호출)
위의 소스코드는 코드 작성 이외의 다른 설정은 하지 않았습니다. dll의 구현은 함수 단위로 되어있습니다.
dll을 클래스 단위로 구현한다면 어떻게 사용해야 할까요? 코드로 보겠습니다.
- DLL 소스코드(Class)
- App 소스코드 (Class)
위와 같이 사용한다면 class 또한 사용이 가능합니다. 만약에 암시적으로 사용하고 싶다면, LoadLibrary() 함수와 GetProcAddress () 함수를 사용해야 하야 합니다. 하지만 GetProcAddress() 함수에 들어가는 두번째 매개변수는 함수명 또는 서수가 들어가야 합니다. C++의 함수는 사용 할 수 없기 때문에 [extern "C"] 를 사용해야 합니다. 그래서 그 함수에서는 new CSwapClass()를 반환한다면 사용이 가능합니다.
※ 암시적 연결을 사용해서 함수 호출을 할려했더니 저는 애러는 나지 않았는데 정확한 주소
를 못 얻어오더군요.. 좀 더 공부를 해봐야 할 듯 합니다.
지금까지 암시적/명시적 연결로 DLL을 사용하는 방법을 알아봤습니다. 모두 열공하세요.
ps. Error C2491이 발생하신 분은 한번 보시기 바랍니다.(Microsoft 영문)
링크 : http://support.microsoft.com/kb/815647/en-us/
O 정적 라이브러리(.LIB)
정적 라이브러리(lib)를 만드는 법은 간단합니다. Visual Studio 2008에서 프로젝트 구성 형식을 정적 라이브러리(.lib)로 만들고 실행을 하면 되기 때문입니다. 이용을 하려면 이 라이브러리(.lib)와 해더 파일(.h)을 이 라이브러리를 이용할 프로젝트에 추가해주면, 이용 또한 쉽습니다.
- 프로젝트에 추가 방법 [첫번째]
1. [프로젝트 - 속성] 선택
2. [링커 - 일반]탭을 선택 후, '추가 라이브러리 디렉터리'에 lib 파일의 경로를 추가.
3. [링커 - 입력]탭을 선택 후, '추가 종속성' 란에 lib 파일을 입력하고, 확인을 누름.
- 프로젝트에 추가 방법 [두번째]
1. main.cpp(App 소스코드를 말함)에서 아래와 같이 입력합니다.
#include "XXX.h" // .h 파일의 경로를 입력한다. 또는 프로젝트에 그 폴더를 포함시킨다.
#pragma comment(lib, "XXX.lib") // lib경로를 입력해야한다. 속성창에서 하는 일과 같다.
void main()
{
......
}
#pragma comment(lib, "XXX.lib") // lib경로를 입력해야한다. 속성창에서 하는 일과 같다.
void main()
{
......
}
O 동적 라이브러리(.DLL)
동적 라이브러리 또한 정적 라이브러리와 같이 사용이 가능합니다. dll로 프로젝트를 만들고 실행을 하게 되면 dll과 lib 파일이 생성됩니다. 여기서 lib파일에는 dll에 구현된 함수를 찾을 수 있는 정보가 있습니다.(저두 본거라...) 그래서 정적 라이브러리와 같은 방법으로 사용이 가능합니다. 이런 방식을 '암시적 연결'이라고 합니다.
암시적 연결 방법만 있는 것은 아닙니다. 명시적 방법 또한 있습니다. 이 방법은 dll 파일만 있어도 사용 할 수 있습니다. 하지만 C스타일의 함수여야 하는 듯 합니다. 아래를 보시면 아시겠지만 함수의 이름으로 주소를 얻어오기 때문에 C++에서 사용 할 수 있는 오버로딩이 되지 않습니다. 오버로딩이란 함수의 이름은 같지만 매개변수가 다를 경우 다른 함수로 간주 하는 것을 말합니다.
한번 코드로 정리 해보겠습니다. 첫번째는 헤더와 lib파일을 이용해서 dll을 사용하는 방법입니다.
- DLL 소스코드
//Swap.h
#ifndef __SWAP_H__
#define __SWAP_H__
#ifdef DLL_EXPORT
#define DLLTYPE __declspec(dllexport)
#else
#define DLLTYPE __declspec(dllimport)
#endif //DLL_EXPORT
extern "C" DLLTYPE void SwapInt(int* dest, int* src);
extern "C" DLLTYPE void SwapStr(char* dest, char* src, int size);
#endif //__SWAP_H__
#ifndef __SWAP_H__
#define __SWAP_H__
#ifdef DLL_EXPORT
#define DLLTYPE __declspec(dllexport)
#else
#define DLLTYPE __declspec(dllimport)
#endif //DLL_EXPORT
extern "C" DLLTYPE void SwapInt(int* dest, int* src);
extern "C" DLLTYPE void SwapStr(char* dest, char* src, int size);
#endif //__SWAP_H__
//Swap.cpp
#define DLL_EXPORT
#include "Swap.h"
void SwapInt(int* dest, int* src)
{
int temp = *dest;
*dest = *src;
*src = temp;
}
void SwapStr(char* dest, char* src, int size)
{
char* pcTemp = new char[size];
for(int i = 0 ; i < size ; i++)
{
pcTemp[i] = dest[i];
dest[i] = src[i];
src[i] = pcTemp[i];
}
delete [] pcTemp;
}
#define DLL_EXPORT
#include "Swap.h"
void SwapInt(int* dest, int* src)
{
int temp = *dest;
*dest = *src;
*src = temp;
}
void SwapStr(char* dest, char* src, int size)
{
char* pcTemp = new char[size];
for(int i = 0 ; i < size ; i++)
{
pcTemp[i] = dest[i];
dest[i] = src[i];
src[i] = pcTemp[i];
}
delete [] pcTemp;
}
- App 소스코드1 (.h + .lib 이용하여 dll 함수 호출)
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include "..\SwapDll\Swap.h"
#pragma comment(lib, "..\\Debug\\SwapDll.lib")
int main()
{
int a = 10, b = 20;
#include <windows.h>
#include <tchar.h>
#include "..\SwapDll\Swap.h"
#pragma comment(lib, "..\\Debug\\SwapDll.lib")
int main()
{
int a = 10, b = 20;
printf("\t\ta : %d, b : %d\n", a, b);
SwapInt(&a,&b);
printf("swap --> \ta : %d, b : %d\n", a, b);
return 0;
}
SwapInt(&a,&b);
printf("swap --> \ta : %d, b : %d\n", a, b);
return 0;
}
- App 소스코드2 (WinAPI를 이용하여 dll 함수 호출)
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
typedef void (*Func)(int*, int*);
int main()
{
int a = 10, b = 20;
HINSTANCE hDll = LoadLibrary(_T("SwapDll.dll"));
if(hDll == NULL)
{
printf("dll 로드 실패\n");
return -1;
}
Func pFunc = (Func)GetProcAddress(hDll, "SwapInt");
Func pFunc1 = (Func)GetProcAddress(hDll, "SwapStr");
printf("\t\ta : %d, b : %d\n", a, b);
pFunc(&a,&b);
printf("swap --> \ta : %d, b : %d\n", a, b);
FreeLibrary(hDll);
return 0;
}
#include <windows.h>
#include <tchar.h>
typedef void (*Func)(int*, int*);
int main()
{
int a = 10, b = 20;
HINSTANCE hDll = LoadLibrary(_T("SwapDll.dll"));
if(hDll == NULL)
{
printf("dll 로드 실패\n");
return -1;
}
Func pFunc = (Func)GetProcAddress(hDll, "SwapInt");
Func pFunc1 = (Func)GetProcAddress(hDll, "SwapStr");
printf("\t\ta : %d, b : %d\n", a, b);
pFunc(&a,&b);
printf("swap --> \ta : %d, b : %d\n", a, b);
FreeLibrary(hDll);
return 0;
}
위의 소스코드는 코드 작성 이외의 다른 설정은 하지 않았습니다. dll의 구현은 함수 단위로 되어있습니다.
dll을 클래스 단위로 구현한다면 어떻게 사용해야 할까요? 코드로 보겠습니다.
- DLL 소스코드(Class)
//SwapClass.h
#ifndef __SWAP_CLASS_H__
#define __SWAP_CLASS_H__
#ifdef DLL_EXPORT_CLASS
#define DLLTYPE __declspec(dllexport)
#else
#define DLLTYPE __declspec(dllimport)
#endif //DLL_EXPORT_CLASS
class DLLTYPE CSwapClass
{
public:
CSwapClass();
~CSwapClass();
void Int(int* dest, int* src);
void String(char* dest, char* src, int size);
};
#endif //__SWAP_CLASS_H__
#ifndef __SWAP_CLASS_H__
#define __SWAP_CLASS_H__
#ifdef DLL_EXPORT_CLASS
#define DLLTYPE __declspec(dllexport)
#else
#define DLLTYPE __declspec(dllimport)
#endif //DLL_EXPORT_CLASS
class DLLTYPE CSwapClass
{
public:
CSwapClass();
~CSwapClass();
void Int(int* dest, int* src);
void String(char* dest, char* src, int size);
};
#endif //__SWAP_CLASS_H__
//SwapClass.cpp
#define DLL_EXPORT_CLASS
#include "SwapClass.h"
CSwapClass::CSwapClass()
{
}
CSwapClass::~CSwapClass()
{
}
void CSwapClass::Int(int* dest, int* src)
{
int temp = *dest;
*dest = *src;
*src = temp;
}
void CSwapClass::String(char* dest, char* src, int size)
{
char* pcTemp = new char[size];
for(int i = 0 ; i < size ; i++)
{
pcTemp[i] = dest[i];
dest[i] = src[i];
src[i] = pcTemp[i];
}
delete [] pcTemp;
}
#define DLL_EXPORT_CLASS
#include "SwapClass.h"
CSwapClass::CSwapClass()
{
}
CSwapClass::~CSwapClass()
{
}
void CSwapClass::Int(int* dest, int* src)
{
int temp = *dest;
*dest = *src;
*src = temp;
}
void CSwapClass::String(char* dest, char* src, int size)
{
char* pcTemp = new char[size];
for(int i = 0 ; i < size ; i++)
{
pcTemp[i] = dest[i];
dest[i] = src[i];
src[i] = pcTemp[i];
}
delete [] pcTemp;
}
- App 소스코드 (Class)
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include "..\SwapClassDll\SwapClass.h"
#pragma comment(lib, "..\\Debug\\SwapClassDll.lib")
int main()
{
int a = 10, b = 20;
CSwapClass swaper;
printf("\t\ta : %d, b : %d\n", a, b);
swaper.Int(&a,&b);
printf("swap --> \ta : %d, b : %d\n", a, b);
return 0;
}
#include <windows.h>
#include <tchar.h>
#include "..\SwapClassDll\SwapClass.h"
#pragma comment(lib, "..\\Debug\\SwapClassDll.lib")
int main()
{
int a = 10, b = 20;
CSwapClass swaper;
printf("\t\ta : %d, b : %d\n", a, b);
swaper.Int(&a,&b);
printf("swap --> \ta : %d, b : %d\n", a, b);
return 0;
}
위와 같이 사용한다면 class 또한 사용이 가능합니다. 만약에 암시적으로 사용하고 싶다면, LoadLibrary() 함수와 GetProcAddress () 함수를 사용해야 하야 합니다. 하지만 GetProcAddress() 함수에 들어가는 두번째 매개변수는 함수명 또는 서수가 들어가야 합니다. C++의 함수는 사용 할 수 없기 때문에 [extern "C"] 를 사용해야 합니다. 그래서 그 함수에서는 new CSwapClass()를 반환한다면 사용이 가능합니다.
※ 암시적 연결을 사용해서 함수 호출을 할려했더니 저는 애러는 나지 않았는데 정확한 주소
를 못 얻어오더군요.. 좀 더 공부를 해봐야 할 듯 합니다.
지금까지 암시적/명시적 연결로 DLL을 사용하는 방법을 알아봤습니다. 모두 열공하세요.
ps. Error C2491이 발생하신 분은 한번 보시기 바랍니다.(Microsoft 영문)
링크 : http://support.microsoft.com/kb/815647/en-us/
반응형
'프로그래밍 > Windows API' 카테고리의 다른 글
GetLastError() 함수로 얻는 애러코드 (0) | 2010.12.11 |
---|---|
동적 링크 라이브러리(DLL) 사용 / 만들기 #2 (0) | 2010.11.12 |
MultiByteToWideChar와 WideCharToMultiByte 함수 (2) | 2010.11.09 |
INI 파일 제어 함수 (Get...Profile... / Write...Profile...) (0) | 2010.11.04 |
API 함수 레퍼런스 (0) | 2010.11.04 |
레지스터 관련 - RegSetValueEx 함수 (0) | 2010.10.27 |
레지스터 관련 - RegOpenKeyEx 함수 (0) | 2010.10.27 |
꼭 알아야 할 필수 API 함수 (0) | 2010.10.27 |
레지스터 관련 - RegCreateKeyEx 함수 (0) | 2010.10.27 |
Windows 와 Linux Thread Control 함수 비교 (동기화 함수) (0) | 2010.10.27 |