2013-06-11 2 views
1

우리는 인터페이스 클래스DLL 내보내기 및 가상 메소드 윈도우 프로젝트에서

class Interface { 
public: 
    virtual ~Interface() { } 
    virtual void func() = 0; 
}; 

과 DLL 내부의 공장 기능

__declspec(dllexport) Interface *construct(); 

을 정의합니다. 물론 Interface의 구체적인 전문화가 DLL 내에 있지만 우리는 그것을 내 보내지 않습니다. 그럼에도 불구하고 DLL 외부에서 사용할 수 있습니다. 이게 어떻게 작동합니까? construct()에 의해 생성 된 인스턴스의 vftable은 DLL에서 내 보내지 않은 함수 포인터 대상 함수로 구성됩니다. 이 접근 방식을 수용 할 수 있습니까?

답변

3

구체적인 클래스를 내보낼 필요가 없습니다. 인터페이스 포인터에서 얻은 v-table은 DLL 내부에 저장된 구체적인 v-table로 설정됩니다. 어떤 구현 포인터에 이미 모든 함수 포인터가 올바르게 설정되어 있습니다. 일단 v-table 포인터를 얻으면 황금이되어 구체적인 방법을 호출 할 수 있습니다. COM과 비교하면 팩토리 함수 (DllGetClassObject)가 아닌 COM 서버에서 아무 것도 내보내지 않습니다.

do은 construct() 함수를 내 보내야합니다. 외부 코드가이 함수의 주소를 가져올 수있는 다른 방법은 없습니다. 함수 이름을 함수 주소에 매핑하는 조회 테이블이 필요합니다. DLL의 내보내기 테이블. 함수와 클래스를 내보내기하면 해당 내보내기 테이블에 항목이 추가됩니다.

+0

그래서 COM이 공장 기능을 제외한 모든 것을 내 보내지 않으면 너무 많이 받아 들여야합니다. – phlipsy

+0

그리고 v-table의 레이아웃은'Interface'를 정의하는 공개적으로 사용 가능한 헤더에서 나온 것인가? – phlipsy

+0

예, 대략 인터페이스의 선언에 따라 빌드하는 것은 컴파일러입니다. DLL 지옥의 다소 불명예스러운 소스는 버전 관리가 어렵습니다. 인터페이스의 새로운 선언을 사용하고 실수로 DLL의 이전 버전을로드하는 클라이언트는 심하게 충돌합니다. COM에서 변경 한 인터페이스 IID를 항상 변경해야하는 핵심 이유가 있습니다. –