2012-02-09 2 views
2

다음과 같은 인터페이스 인스턴스 생성 방법을 만들었습니다.CreateInstance 루틴을위한 템플릿 함수

static IFBIndexItem* CreateFBIndexItemPtr() 
{ 
    IFBIndexItemPtr pFBComWrapper; 
    HRESULT hr = pFBComWrapper.CreateInstance(__uuidof(FBIndexItem)); 
    if (FAILED(hr)) { 
     throw new _com_error(hr); 
    } 
    return pFBComWrapper; 
} 

잘 작동하지만 여러 인터페이스가 있기 때문에 템플릿 방법을 만들고 싶습니다. 결과적으로 여기에있는 메소드가 있지만 "Class not registered"예외가 발생합니다.

template<class T> 
static T* CreateInterfacePtr() 
{ 
    _com_ptr_t <_com_IIID<T, &__uuidof(T)>> pFBComWrapper; 
    HRESULT hr = pFBComWrapper.CreateInstance(__uuidof(T)); 
    if (FAILED(hr)) { 
     throw new _com_error(hr); 
    } 
    return pFBComWrapper; 
} 

왜 제대로 작동하지 않는지 궁금합니다. 감사.

+0

는 같은 함수를 호출 할 필요가 있음을 기억하십시오. 오류가 무엇입니까? – iammilind

답변

2

문제는 클래스 ID 대신 인터페이스의 UUID를 CreateIsntance()으로 전달하는 것입니다.

물론 CreateInstance()처럼 사용하면 인터페이스와 동일한 ID를 가진 (일반적으로) COM이 노출 된 클래스가 없습니다. 또한 하나 이상의 클래스가 동일한 인터페이스를 구현할 수 있으므로 동일한 인터페이스에 대해 서로 다른 클래스 ID를 전달할 수 있어야합니다.

따라서 함수에는 인터페이스와 클래스 ID (또는 __uuidof을 사용하여 클래스 ID를 얻을 수있는 클래스 자체)의 두 매개 변수가 있어야합니다.

또한 코드에 심각한 소유권 문제가 있습니다. 이 함수는 함수가 반환 될 때 파기되는 스마트 포인터에서 추출한 원시 포인터를 반환합니다. 이렇게하면 개체가 해제되고 포인터가 매달리게됩니다.

+0

도움 주셔서 감사합니다. 소유권 문제를 제거하는 방법에 대한 제안이 있습니까? – kandreych

+0

@kandreych : 스마트 포인터를 반환 할 수도 있고,'Detach()'를 호출하여 미처리 포인터를 반환 할 수도 있습니다. – sharptooth

0

그래서 여기에 작동 코드가 있습니다, sharptooth의 대답에 따르면 맞을 것 같습니다.

template<class C, class T> 
static C* CreateInterfacePtr() 
{ 
    _com_ptr_t <_com_IIID<C, &__uuidof(C)>> pInterface; 
    HRESULT hr = pInterface.CreateInstance(__uuidof(T)); 
    if (FAILED(hr)) { 
     throw new _com_error(hr); 
    } 
    return pInterface.Detach(); 
} 

전화 :`CreateInterfacePtr ()`:

CComPtr<IFBFileInfo> item = CreateInterfacePtr<IFBItem, FBItem>();