2010-07-08 6 views
1

코드 프로젝트에서이 article을 우연히 만났습니다.이 프로젝트에서는 이름 변환 문제를 피하기 위해 C++ DLL에서 전체 클래스를 내보내는 대신 추상 인터페이스를 사용하는 방법에 대해 설명합니다. 작성자는 자신의 인터페이스 정의에 Release() 메소드를 가지고 있습니다.이 메소드는 사용자가 클래스 오브젝트의 자원을 사용 한 후에 해제하도록 호출해야합니다. 이 메서드의 호출을 자동화하기 위해 저자는 객체를 삭제하기 전에 Release() 메서드를 호출하는 std::auto_ptr<T>과 같은 클래스를 만듭니다.DLL에서 C++ 클래스 내보내기

나는 다음과 같은 접근 방식 대신 일하는 것이 있는지 궁금 해서요 :

물론
#include <memory> 

#if defined(XYZLIBRARY_EXPORT) // inside DLL 
# define XYZAPI __declspec(dllexport) 
#else // outside DLL 
# define XYZAPI __declspec(dllimport) 
#endif // XYZLIBRARY_EXPORT 

// The abstract interface for Xyz object. 
// No extra specifiers required. 
struct IXyz 
{ 
    virtual int Foo(int n) = 0; 

    //No Release() method, sub-class' destructor does cleanup 
    //virtual void Release() = 0; 

    virtual ~IXyz() {} 
}; 

// Factory function that creates instances of the Xyz object. 
// Private function, do not use directly 
extern "C" XYZAPI IXyz* __stdcall GetXyz_(); 

#define GetXyz()  std::auto_ptr<IXyz>(GetXyz_()) 

, GetXyz() 대신 #define의 헤더에 정의 된 전역 함수가 될 수 있습니다. 이 방법의 장점은 Release() 메서드를 호출하는 auto_ptr의 고유 파생어를 취할 필요가 없다는 것입니다.

답변 해 주셔서 감사합니다. Ashish.

답변

3

이렇게하면 new()와 일치하는 호출로 생성되지 않은 객체에서 delete (auto_ptr의 소멸자 내에서 프로세스에서)를 호출 할 위험이 있습니다 (즉, 팩토리 함수 내에서 수행되므로 dll 내부에서 수행됩니다) . 디버그 모드에서 호출 프로세스를 수행하는 동안 dll이 릴리스 모드로 컴파일되는 경우와 같이 문제가 발생하지 않습니다.

Release() 메소드가 더 좋습니다.

+0

감사합니다. 나는 CRT의 메모리 관리 모델이 다르다고 생각하지 않았습니다. 디버그 및 릴리스 버전에서는 문제가 될뿐만 아니라 DLL (또는 호출자)이 정적으로 CRT에 연결되어 있고 다른 하나는 동적으로 링크 된 경우 Greg Domjan이 아래에서 언급했듯이 문제가 될 수 있습니다. 'Release()'메소드를 가리키는 커스텀 Deleter를 가지고'std :: tr1 :: shared_ptr'을 사용하여 끝내게되었습니다. – Praetorian

2

정확히 COM의 작동 방식입니다. Win32 API를 이미 목표로 삼고 있다면이 휠을 다시 발명하는 것을 피하십시오. Windows 인터페이스 프로그래밍에서 스마트 포인터를 사용하여 COM 인터페이스 포인터를 저장하는 것은 소멸자가 Release() 메서드를 호출합니다. _com_ptr_t 및 CComPtr에 대한 아이디어를 보려면 MSDN 문서를 살펴보십시오.

1

공개 API 인 경우 사용자가 직면하는 제한 사항은 다른 모듈이 연결될 CRT와 개체를 만드는 CRT도 삭제해야하는 CRT입니다.

오른쪽 CRT를 선택하지 않으면 엉망이 될 것입니다 메모리 관리를 공유하는 것은 CRT (또는 기타 메모리 할당)를 외부 라이브러리로 사용해야합니다. MSVC : 다중 스레드 DLL (/ MD)

주어진 경우 서브 클래스가 목적을 달성 할 필요가 없습니다.

관련 문제