MFC Dll 생성 및 사용
1. DLL의 종류 :
일반 DLL – Win32 DLL (비 MFC), MFC DLL
모든 Windows Application 에서 사용가능.
VC, C++ 이외 VB, java, C#등 타 언어로 작성된 Application에서도 호출 가능
확장 DLL – MFC를 사용한 확장 DLL
MFC를 사용한 Application에서만 사용 가능함.
2. DLL(Dynamic-Link Library 동적 링크 라이브러리)의 특징 :
· 응용 프로그램의 경우에는 시스템에서 해당 인스턴스가 동시에 여러 개 실행될 수 있지만 DLL의 경우에는 하나의 인스턴스만 실행됩니다. (중요!)
· 응용 프로그램에는 스택, 전역 메모리, 파일 핸들 및 메시지 큐 등이 포함될 수 있지만 DLL은 그렇지 않습니다.
3. VS에서 DLL 프로젝트 작성하기(MFC 확장 DLL의 경우)
VS에서 [새 프로젝트] – [Visual C++] – [MFC] – [MFC DLL]
MFC DLL 마법사에서 MFC 확장 DLL로 선택
4. DLL 외부에서 호출되는 함수 정의
extern "C" __declspec(dllexport) [반환값의 형] [함수명] ( [호출 파라미터] )
Ex:)
extern "C" __declspec(dllexport) int xMyFunction(int nParam)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return nMyFunction(nParam);
}
아래 매크로는 각 함수에 반드시 포함되어야 하며, 첫 번째 문이어야 함.
AFX_MANAGE_STATE(AfxGetStaticModuleState());
전역함수 선언에 “extern "C" __declspec(dllexport)” 키워드를 붙여
DLL 외부에서 호출 가능하도록 만들어 주는 이외에는
일반적인 전역함수와 작성/사용법이 동일함.
5. 외부에서 DLL의 함수를 호출하는 경우
typedef [반환값의 형] (* [함수포인트로 사용할 변수형의 이름]
typedef int(*nMyFunction)(int nParam);
// CxMyDlg 대화 상자
class CxMYDlg : public CDialogEx
{
// 생성입니다.
public:
nMyFunction m_nMyFunction;
typedef를 이용하여 DLL에서 호출할 함수의 형태와 동일한 함수 포인터를 작성한 후,
DLL을 호출할 Class의 멤버로
nMyFunction m_nMyFunction;
와 같이 선언함.
m_nMyFunction은 함수 포인트이며 이 시점에서는 아직 사용할 수 없음.
이후, 초기화 함수 등에서 다음과 같이 실재 DLL의 함수와 연결해 주어야 사용할 수 있음.
HINSTANCE m_hMYDLL = LoadLibrary("myDLL.dll");
if (m_hMYDLL == NULL)
return false;
m_nMyFunction = (nMyFunction)GetProcAddress(m_hMYDLL , "xMyFunction");
nMyFunction– typedef로 선언한 함수형의 이름
“xMyFunction” – DLL에서 선언한 함수의 이름.
*함수형과 GetProcAddress에 지정된 함수명이 정확히 일치하여야 함수 포인터를 가져오며
실패할 경우, 함수 포인터가 NULL이 됨.
함수 포인터가 연결된 이후에는
m_nMyFunction (3);
와 같이 일반 함수처럼 사용할 수 있음.
6. CallBack 함수의 작성.
DLL의 함수를 외부에서 호출하여 사용하는 경우와 반대로
DLL에서 특정 이벤트 등이 발생한 경우, 이를 Dll을 Embed하고 있는 Application에서 전달받아 처리하려는 경우, DLL에서 Application쪽으로 이벤트 등을 전달할 수단이 필요함.
이를 해결하는 한 방법으로 Application에 선언된 함수의 포인터를 DLL에 전달하고 필요한 경우,
이를 DLL에서 호출될 수 있도록 CallBack 함수를 등록하여 사용함.
- DLL에서의 CallBack 등록 함수의 예.
void(*pCallBack_ProcessEvent)(int type, char *msg);
//Dll 외부로 Event전달하기 위한 Callback Function을 등록
extern "C" __declspec(dllexport) void xSetCallBackFunc(LPVOID lpCallbackFunc)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
pCallBack_ProcessEvent = (void(__cdecl*)(int type, char *msg))lpCallbackFunc;
}
- Application에서 CallBack 함수 선언의 예
void CallBack_ProcessEvent(int type, char *msg)
{
if (mainDlg)
mainDlg->ProcessEvent(type, msg);
}
* 샘플에서는 전역함수를 CallBack으로 선언한 후, mainDlg의 함수를 내부에서 호출하고 있음.
- Application에서 CallBack 등록 함수 호출 및 CallBack 함수의 등록
m_nSetCallBackFunc((void*)CallBack_ProcessEvent);
* m_nSetCallBackFunc에 대해서도 5번의 선언 및 LoadLibrary를 통한 함수 연결을 동일하게 수행하여야 함.