Здравствуйте, Аноним, Вы писали:
А>У меня еесть интерфейс 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");
}
Супер. Спасибо большое
Здравствуйте, Аноним, Вы писали:
А>Как мне преобразовать этот CComPtr в указатель на CMyObj, чтобы вызывать эти методы?
Есть FAQ
ИНФО: Как получить Cx из Ix*Автор: Vi2
Дата: 17.06.02
от Микрософт и обсуждение его в
ИНФО: Как получить Cx из Ix*Автор: Vi2
Дата: 17.06.02
.