Функция шаблона для подпрограмм CreateInstance - PullRequest
2 голосов
/ 09 февраля 2012

Я сделал следующий метод для создания экземпляра интерфейса.

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

Он работает нормально, но, поскольку у меня несколько интерфейсов, я хочу создать шаблонный метод.Итак, вот приведенный метод, но он выдает исключение «Класс не зарегистрирован».

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;
}

Интересно, почему он не работает правильно.Спасибо.

Ответы [ 2 ]

2 голосов
/ 09 февраля 2012

Проблема в том, что вы передаете UUID интерфейса вместо идентификатора класса в CreateIsntance().

Конечно, CreateInstance() не будет работать при таком использовании - нет (обычно) COM-незащищенногокласс с тем же идентификатором, что и интерфейс.Кроме того, несколько классов могут реализовывать один и тот же интерфейс, поэтому, естественно, вы захотите передавать разные идентификаторы классов для одного и того же интерфейса.

Следовательно, вам необходимо иметь два параметра в вашей функции - интерфейс иидентификатор класса (или сам класс, из которого вы можете получить идентификатор класса, используя __uuidof).

Также у вас есть серьезная проблема владения в вашем коде.Функция возвращает необработанный указатель, извлеченный из умного указателя, который уничтожается при возврате из функции.Скорее всего, это приведет к освобождению объекта и зависанию указателя.

0 голосов
/ 22 февраля 2012

Итак, вот рабочий код, кажется правильным в соответствии с ответом 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();
}

Вызов:

CComPtr<IFBFileInfo> item = CreateInterfacePtr<IFBItem, FBItem>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...