다음을 통해 공유


AFX_EXT_CLASS를 사용하여 내보내기 및 가져오기

확장 DLLAFX_EXT_CLASS 매크로를 사용하여 클래스를 내보내고, 확장 DLL에 링크하는 실행 파일은 이 매크로를 사용하여 클래스를 가져옵니다. AFX_EXT_CLASS 매크로를 사용하는 경우에는 확장 DLL을 빌드하는 데 사용되는 것과 동일한 헤더 파일을 해당 DLL을 링크하는 실행 파일에도 사용할 수 있습니다.

DLL에 대한 헤더 파일에서 다음과 같이 클래스 선언에 AFX_EXT_CLASS 키워드를 추가합니다.

class AFX_EXT_CLASS CMyClass : public CDocument
{
// <body of class>
};

이 매크로는 전처리기 기호인 _AFXDLL_AFXEXT가 정의될 때 MFC에서 **__declspec(dllexport)**으로 정의됩니다. 그러나 _AFXDLL은 정의되고 _AFXEXT가 정의되지 않으면 이 매크로는 **__declspec(dllimport)**으로 정의됩니다. 전처리기 기호 _AFXDLL이 정의된 경우 이 기호는 대상 실행 파일(DLL 또는 응용 프로그램)에서 MFC의 공유 버전을 사용하고 있음을 나타냅니다. _AFXDLL_AFXEXT가 모두 정의된 경우에는 대상 실행 파일이 확장 DLL임을 나타냅니다.

AFX_EXT_CLASS는 확장 DLL에서 내보낼 때 **__declspec(dllexport)**으로 정의되기 때문에 해당 클래스의 모든 기호에 대한 데코레이팅된 이름을 .def 파일에 포함하지 않고도 전체 클래스를 내보낼 수 있습니다. 이 방법은 MFC 샘플 DLLHUSK에서 사용됩니다.

이 방법을 사용할 경우 .def 파일과 해당 클래스의 모든 데코레이팅된 이름을 만들지 않아도 되지만, .def 파일을 만들면 이 이름을 서수로 내보낼 수 있으므로 좀 더 효율적입니다. .def 파일을 사용하여 내보내려면 헤더 파일의 처음과 끝 부분에 다음 코드를 추가합니다.

#undef AFX_DATA
#define AFX_DATA AFX_EXT_DATA
// <body of your header file>
#undef AFX_DATA
#define AFX_DATA

경고

인라인 함수를 내보낼 때에는 버전 충돌이 발생할 수 있으므로 주의해야 합니다. 인라인 함수는 응용 프로그램 코드로 확장됩니다. 따라서 나중에 이 함수를 다시 쓰는 경우 해당 응용 프로그램을 다시 컴파일해야만 함수가 업데이트됩니다. 반면, 일반적인 DLL 함수는 해당 함수를 사용하는 응용 프로그램을 다시 빌드하지 않아도 업데이트됩니다.

클래스의 개별 멤버 내보내기

때로는 클래스의 개별 멤버를 내보내려는 경우가 있습니다. 예를 들어, CDialog 파생 클래스를 내보내는 경우 해당 생성자 및 DoModal 호출만 내보내야 하는 경우가 있습니다. 이런 경우에는 내보내야 할 개별 멤버에 AFX_EXT_CLASS를 사용하면 됩니다.

예를 들면 다음과 같습니다.

class CExampleDialog : public CDialog
{
public:
   AFX_EXT_CLASS CExampleDialog();
   AFX_EXT_CLASS int DoModal();
   ...
   // rest of class definition
   ...
};

해당 클래스의 모든 멤버를 더 이상 내보내지 않으므로 MFC 매크로의 작동 방식으로 인한 추가 문제가 발생할 수 있습니다. MFC의 일부 도우미 매크로에서는 실제로 데이터 멤버를 선언하거나 정의합니다. 따라서 이러한 데이터 멤버도 DLL에서 내보내야 합니다.

예를 들어, 확장 DLL을 빌드할 때에는 다음과 같이 DECLARE_DYNAMIC 매크로가 정의됩니다.

#define DECLARE_DYNAMIC(class_name) \
protected: \
   static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
   static AFX_DATA CRuntimeClass class##class_name; \
   virtual CRuntimeClass* GetRuntimeClass() const; \

static AFX_DATA로 시작하는 줄은 클래스 내부의 정적 개체를 선언합니다. 이 클래스를 올바르게 내보내고 클라이언트 실행 파일에서 런타임 정보에 액세스하려면 이 정적 개체를 내보내야 합니다. 정적 개체는 AFX_DATA 한정자를 사용하여 선언되기 때문에 이 AFX_DATA를 DLL 빌드 시에는 **__declspec(dllexport)**으로 정의하고 클라이언트 실행 파일 빌드 시에는 **__declspec(dllimport)**으로 정의합니다. AFX_EXT_CLASS는 이미 이러한 방식으로 정의되어 있으므로 클래스 정의 부분에서 AFX_DATAAFX_EXT_CLASS와 동일하게 다시 정의합니다.

예를 들면 다음과 같습니다.

#undef  AFX_DATA
#define AFX_DATA AFX_EXT_CLASS

class CExampleView : public CView
{
   DECLARE_DYNAMIC()
   // ... class definition ...
};

#undef  AFX_DATA
#define AFX_DATA

MFC는 해당 매크로 내에서 정의하는 데이터 항목에 대해 항상 AFX_DATA 기호를 사용하므로 이 기술은 이러한 모든 시나리오에 적용됩니다. 예를 들어, 이 기술은 DECLARE_MESSAGE_MAP에도 적용됩니다.

참고

클래스에서 선택한 멤버만 내보내는 것이 아니라 전체 클래스를 내보내는 경우에는 정적 데이터 멤버가 자동으로 내보내집니다.

수행할 작업

추가 정보

참고 항목

개념

DLL에서 내보내기