다음을 통해 공유


확장 DLL 초기화

업데이트: 2007년 11월

확장 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
}

초기화하는 동안 새 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에는 이 헤더 파일을 포함시켜야 합니다.

참고:

Stdafx.h에 있는 모든 _AFX_NO_XXX 매크로에 대해서 정의하거나 정의를 해제하지 않아야 합니다. 자세한 내용은 기술 자료 문서의 "PRB: Problems Occur When Defining _AFX_NO_XXX"(Q140751)를 참조하십시오. 기술 자료 문서는 MSDN Library나 http://search.support.microsoft.com/에서 찾을 수 있습니다.

다중 스레딩을 처리하는 샘플 초기화 함수는 Windows SDK의 Using Thread Local Storage in a Dynamic-Link Library에 포함되어 있습니다. 이 샘플에는 LibMain이라는 진입점 함수가 포함되어 있지만 이 함수가 MFC 및 C 런타임 라이브러리와 함께 작동하도록 하려면 이 함수 이름을 DllMain으로 변경해야 합니다.

MFC 샘플 DLLHUSK에서는 초기화 함수의 사용 방법을 보여 줍니다.

수행할 작업

추가 정보

참고 항목

개념

DLL 초기화