본문으로 바로가기

DLL에서 만든 클래스 공유

category 개발언어/c++ 2016. 7. 18. 05:12

AFX_EXT_CLASS를 사용한 클래스 공유

DLL 내부에서 만든 Class 혹은 Struct에 AFX_EXT_CLASS을 추가하면 이름 참조하는

프로젝트에서 해당 Class를 직접 불러서 사용할 수 있습니다.

예를 들어 Dll Project에

class AFX_EXT_CLASS CExcuteDB : public CDaoDatabase

{

}

와 같은 형태로 클래스를 만들었다면 이 DLL을 사용하는 Project에서 CExcuteDB를 직접 불러올 수 있습니다.

Void main()

{

CExcuteDB mydb;//

}

 

확장 DLL에서 만든 클래스 공유

확장 DLL에는 기본 DLL과 달리 CWinApp 파생 개체가 없기 때문에 MFC DLL 마법사가 생성하는

DllMain 함수에 초기화 및 종료 코드를 사용자가 직접 추가해야 합니다.

MFC DLL 마법사에서는 확장 DLL에 대해 다음과 같은 코드를 제공합니다.

아래 코드에서 PROJNAME은 사용자의 프로젝트 이름에 대한 자리 표시자입니다.

#include "stdafx.h"

#include <afxdllx.h>

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

static AFX_EXTENSION_MODULE PROJNAMEDLL = { NULL, NULL };

extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)

{

if (dwReason == DLL_PROCESS_ATTACH)

{

TRACE0("PROJNAME.DLL Initializing!\n");

// Extension DLL one-time initialization

AfxInitExtensionModule(PROJNAMEDLL, hInstance);

// Insert this DLL into the resource chain

new CDynLinkLibrary(Dll3DLL);

}

else if (dwReason == DLL_PROCESS_DETACH)

{

TRACE0("PROJNAME.DLL Terminating!\n");

}

return 1; // ok

}

 

항상 배포전에는 Release를 사용해야 합니다.

debug를 사용하면 하위참조 Class에서 Instance를 먼저 생성하므로 정상 동작 하지 않을 수 있습니다.

초기화하는 동안 새 CDynLinkLibrary 개체를 만들면 확장 DLL이 CRuntimeClass 개체 또는 리소스를 클라이언트 응용 프로그램에 내보낼 수 있습니다.

하나 이상의 기본 DLL에서 확장 DLL을 사용하려면 CDynLinkLibrary 개체를 만드는 초기화 함수를 내보내야 합니다.

이 함수는 확장 DLL을 사용하는 각각의 기본 DLL에서 호출되어야 합니다.

이 초기화 함수는 확장 DLL의 내보내는 클래스 또는 함수를 사용하기 전에

기본 DLL에 포함된 CWinApp 파생 개체의 InitInstance 멤버 함수에서 호출하는 것이 좋습니다.

MFC DLL 마법사가 생성하는 DllMain에서 AfxInitExtensionModule을 호출하면 CDynLinkLibrary 개체가 만들어질 때

사용할 해당 개체 팩터리(COleObjectFactory 개체)와 해당 모듈의 런타임 클래스(CRuntimeClass 구조체)가 캡처됩니다.

이 때 AfxInitExtensionModule의 반환 값을 확인하여 AfxInitExtensionModule에서 0이 반환되면 DllMain 함수에서 0을 반환해야 합니다.

확장 DLL이 실행 파일에 명시적으로 링크되는 경우 즉, 실행 파일이 AfxLoadLibrary를 호출하여 해당 DLL에 링크하는 경우에는

AfxTermExtensionModule에 대한 호출을 DLL_PROCESS_DETACH에 추가해야 합니다.

이 함수를 사용하면 프로세스가 종료되거나 AfxFreeLibrary 호출 결과로 DLL이 언로드되어 각 프로세스가

확장 DLL에서 분리될 때 MFC에서 해당 확장 DLL을 정리합니다.

확장 DLL이 응용 프로그램에 암시적으로 링크되는 경우에는 AfxTermExtensionModule을 호출하지 않아도 됩니다.

확장 DLL에 명시적으로 링크하는 응용 프로그램은 DLL을 해제할 때 AfxTermExtensionModule을 호출해야 합니다.

또한 다중 스레드를 사용하는 응용 프로그램의 경우에는 Win32 함수인 LoadLibraryFreeLibrary 대신 AfxLoadLibraryAfxFreeLibrary를 사용해야 합니다.

AfxLoadLibraryAfxFreeLibrary를 사용하면 확장 DLL이 로드되거나 언로드될 때 실행되는 시작 코드와 종료 코드가 전역 MFC 상태를 손상시키지 않게 됩니다.

MFCx0.dll은 DllMain이 호출될 때 완전히 초기화되므로 16비트 버전의 MFC와는 달리 DllMain 내에서 메모리를 할당하고 MFC 함수를 호출할 수 있습니다.

확장 DLL은 DllMain 함수에서 DLL_THREAD_ATTACHDLL_THREAD_DETACH의 경우를 처리하여 다중 스레드를 관리합니다.

이러한 경우는 스레드가 DLL에서 연결되거나 분리될 때 DllMain에 전달됩니다.

DLL을 연결할 때 TlsAlloc를 호출하면 DLL은 해당 DLL에 연결된 모든 스레드에 대해 TLS(스레드 로컬 저장소) 인덱스를 유지합니다.

헤더 파일 Afxdllx.h에는 AFX_EXTENSION_MODULE, CDynLinkLibrary 등의 확장 DLL에서 사용되는 구조체가 정의됩니다.

확장 DLL에는 이 헤더 파일을 포함시켜야 합니다.

해당 DLL을 참조 하는 프로그램에서는 Release시 에러가 발생하는데 이를 정상적으로 배포 하려면

컴파일 옵션을 아래와 같이 변경해야 합니다.

'개발언어 > c++' 카테고리의 다른 글

프로세서 핸들 조회  (0) 2016.07.18
MFC Extension DLL 사용시 발생하는 에러 검토  (0) 2016.07.18
std::function  (0) 2016.07.18
namespace  (0) 2016.07.18
MS Winows 계열 의 버전 정보를 알아내는 함수  (0) 2016.07.18