2012-02-09 10 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(またはクラスIDを得るためのクラスそのもの)(__uuidof)の2つのパラメータが必要です。

また、あなたのコードに深刻な所有権の問題があります。この関数は、関数が返ったときに破壊されるスマートポインタから抽出された生ポインタを返します。これにより、オブジェクトが解放され、ポインタがぶら下がってしまう可能性があります。

+0

ご協力ありがとうございます。所有権の問題を解決する方法はありますか? – kandreych

+0

@kandreych:スマートなポインタを返すか、 'Detach()'を呼び出して生ポインタを返すことができます。 – sharptooth

0

ここでは、作業コードは、シャープトゥースの答えによると正しいと思われる。

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>(); 
関連する問題