Как CComPtr<IMyObj> привести к CMyObj
От: Аноним  
Дата: 03.03.09 11:36
Оценка:
У меня еесть интерфейс IMyObj, от него делается кокласс CMyObj

В CMyObj есть некоторые методы, которых нет в интерфейсе.

Есть так же CComPtr<IMyObj> — создатеся как CoCreateInstance(__uuidof(CMyObj), NULL, CLSCTX_SERVER);

Как мне пребразовать этот CComPtr в указатель на CMyObj, чтобы вызыввать эти методы?
Re: Как CComPtr<IMyObj> привести к CMyObj
От: Андрей Россия  
Дата: 03.03.09 12:05
Оценка:
Здравствуйте, Аноним, Вы писали:

skip

коротко говоря: никак

интерфейс должен быть отделен от реализации
а иначе получишь кучу граблей, если вдруг вместо CMyObj тебе придет какой-нибудь COtherObj
Re: Как CComPtr<IMyObj> привести к CMyObj
От: SuhanovSergey  
Дата: 07.04.09 14:55
Оценка: 3 (1)
Здравствуйте, Аноним, Вы писали:

А>У меня еесть интерфейс IMyObj, от него делается кокласс CMyObj

А>В CMyObj есть некоторые методы, которых нет в интерфейсе.
А>Есть так же CComPtr<IMyObj> — создатеся как CoCreateInstance(__uuidof(CMyObj), NULL, CLSCTX_SERVER);
А>Как мне пребразовать этот CComPtr в указатель на CMyObj, чтобы вызыввать эти методы?

Думаю, ясно, что это в принипе возможно только для inproc-объектов и когда не задействован никакогй маршалинг.

В большинстве случаев можно сделать обычный static_cast<CMyObj*>(com_ptr.p).
Можно сделать более надёжно и безопасно. Идея в том, чтобы внутренний клиент вызывал стандартный QueryInterface, передав в него какой-нибудь частный GUID, неизвестный внешним клиентам. В качеатве такого GUID-а можно использовать CLSID класса. Этот подход требует поддержки на строне самого объекта CMyObj. Вариант позволяет перестраховаться от случая, когда IMyObj всё-таки реализуется не CMyObj.

Я использовал такой ATL-like код

// common helper declarations
inline HRESULT WINAPI _ImplementationQIFunc(void* pv,
    REFIID riid, LPVOID* ppv, DWORD dw) { *ppv = pv; return S_OK; }

template <class ThisClass, class CastClass>
struct _ImplementationQIFuncStruct
{
    static inline HRESULT WINAPI _ImplementationQIFunc(void* pv,
        REFIID riid, LPVOID* ppv, DWORD dw)
    { *ppv = static_cast<CastClass*>(reinterpret_cast<ThisClass*>(pv)); return S_OK; }
};

#define COM_INTERFACE_ENTRY_IMPLCLASS(iid) \
    COM_INTERFACE_ENTRY_FUNC(iid, 0, _ImplementationQIFunc)

#define COM_INTERFACE_ENTRY_IMPLCLASS2(iid, this_class, cast_class) \
    COM_INTERFACE_ENTRY_FUNC(iid, 0, (&_ImplementationQIFuncStruct<this_class, cast_class>::_ImplementationQIFunc))

#define DECLARE_GETIMPL(impl_class, iid) \
    static impl_class* GetImpl(IUnknown* intf) \
    { \
        impl_class* ret = NULL; \
        if (intf) intf->QueryInterface(iid, (void**)&ret); \
        return ret; \
    }


// example of class definition
class CMyObj: ...
{
    BEGIN_COM_MAP(CMyObj)
        ...
        COM_INTERFACE_ENTRY_IMPLCLASS(CLSID_MyObj)
    END_COM_MAP()
    
    ...
    
    DECLARE_GETIMPL(CMyObj, CLSID_MyObj) 
}


// example of use
if (CMyObj* impl = CMyObj::GetImpl(ptr))
{
   Use(impl);
}
else
{
   Error("Bad IMyObj implementation");
}
Re[2]: Как CComPtr<IMyObj> привести к CMyObj
От: Аноним  
Дата: 07.04.09 17:44
Оценка:
Супер. Спасибо большое
Re: Как CComPtr<IMyObj> привести к CMyObj
От: Vi2 Удмуртия http://www.adem.ru
Дата: 08.04.09 04:11
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как мне преобразовать этот CComPtr в указатель на CMyObj, чтобы вызывать эти методы?


Есть FAQ ИНФО: Как получить Cx из Ix*
Автор: Vi2
Дата: 17.06.02
от Микрософт и обсуждение его в ИНФО: Как получить Cx из Ix*
Автор: Vi2
Дата: 17.06.02
.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.