2015-10-20 136 views
1

如何将LPUNKNOWN pDlg类型转换为我们的类类型。是dynamic_cast很好吗?例如:myclass * myclass_obj; myclass_obj = dynamic_cast < myclass *> pdlg; 请帮助我。LPUNKNOWN的类型转换

+0

我已经给出了答案,但缺少的信息是你的代码是如何以及在哪里获得LPUNKNOWN指针的?知道你是如何得到指针的,并且你的'myclass'类型的继承模型(包括它继承的)是获得正确答案的重要信息。 – selbie

回答

3

LPUNKNOWN是IUnknown pointer instance。 - 这是一个COM对象。您通常不会将COM接口转换回特定的C++类。相反,您可以调用QueryInterface来访问您需要的接口

您没有指定如何或从哪里获得LPUNKNOWN,或者您的C++类的实例如何被创建为该实例。这将有助于知道。

例子:

IUnknown *pUnk = <initialized from where ever> 
IFoo *pFoo = nullptr; 
HRESULT hr = pUnk->QueryInterface(__uuidof(IFoo), &pFoo); 
if (SUCCEEDED(hr)) 
{ 
    pFoo->DoWhatever(); 
} 

你可能直接投它如果COM接口源于同一个进程中,但不会是使用COM对象正确的语义。

+0

Upvoted,因为它是使用COM接口的典型方式,但有用于动态强制转换的用例。例如,当在一个'CMyClass'(COM类)的代码中,你得到一个指向接口('IMyClass')的指针:'CMyClass * myObj = dynamic_cast (ifoo)'来访问私有成员。 –

+0

@SergeBallesta - 同意。当你熟悉COM并知道你在做什么时,你只应该直接在IUnknown上施放。通过问这个问题,OP显示他对COM没有足够的了解,无法安全地做到这一点。 – selbie

+0

请注意,我的示例没有直接投射'IUnknown',而是正确的界面。但我同意你的观点OP应该提供更多的信息。我只想回答*这很好,只要你知道为什么你可以这样做*但你的答案已经存在:-) –

0

大概你的课是用ATL写的?

在这种情况下,我通常做的是申报这样的专用接口:

interface __declspec(uuid("*some GUID here*")) ICheckMyClass : IUnknown 
{ 
    STDMETHOD_(MyClass*,GetMyClass)() PURE; 
}; 

,然后实现在我的类接口:

class MyClass 
    : CComObjectRootEx ... 
    , private ICheckMyClass 
{ 
... 
private: 
    STDMETHODIMP_(MyClass*,GetMyClass)() { return this; } 

    BEGIN_COM_MAP(MyClass) 
     ... 
     COM_INTERFACE_ENTRY(ICheckMyClass) 
    END_COM_MAP() 
}; 

最后,如果您需要安全从IUnknown *投:

ATL::CComQIPtr<ICheckMyClass> check(pDlg); 
MyClass* myClass=(check==0)?0:check->GetMyClass(); 

这看起来可能很啰嗦,但对我来说它有保留在标准COM和ATL机制中的好处,并且不需要运行时类型信息,并不总是在所有平台上都支持。

+0

你也可以直接将'COM_INTERFACE_ENTRY(MyClass)'添加到BEGIN_COM_MAP部分。然后,如果ATL向导没有为您添加MIDL属性,则为MyClass的头声明添加一个MIDL属性。然后你可以很容易地使用QueryInterface或者使用ATL CComPtr类来获得一个直接指向类实例的指针。 – selbie