2016-03-11 47 views
0

this thread,但是当我传递一个字符串到方法,在COM类的字符串是错误的,这里是代码:如何通过ATL COM类对象作为paramater到COM

COM服务器 - Com.idl :

interface IParamClass : IUnknown 
{ 
    [] HRESULT SetString([in] BSTR str); 
} 

interface IMyClass : IUnknown 
{ 
    [] HRESULT PassComClassAsParam([in] IParamClass* parm); 
} 

ParamClass.cpp

class ATL_NO_VTABLE CParamClass : ... 
{ 
... 
public: 
    BSTR m_str; 

    STDMETHOD(SetString)(BSTR str); 
}; 

STDMETHODIMP CParamClass::SetString(BSTR str) 
{ 
    m_str = str; 
    return S_OK; 
} 

MyClass.cpp:

STDMETHODIMP CMyClass::PassComClassAsParam(IParamClass* param) 
{ 
    CParamClass *obj = (CParamClass*)param; 
    BSTR str = obj->m_str; //debugging here, is wrong string 
... 
} 

C#客户:

MyClass myobj = new MyClass(); 
ParamClass param = new ParamClass(); 
param.SetString("Test String!"); 
myobj.PassComClassAsParam(param); 

回答

2

你必须做字符串参数的副本,在这里,因为你没有控制值的寿命:

STDMETHODIMP CParamClass::SetString(BSTR str) 
{ 
    m_str = str; // str is valid here, but you don't know when 
       // the value is destroyed later 
    return S_OK; 
} 

通过您通过m_str使用值的时间变量,该字符串已被释放并被销毁,因此您会看到它“错误”。

典型的解决方案是:

class ATL_NO_VTABLE CParamClass : ... 
{ 
... 
public: 
    CComBSTR m_str; // <<--- Note CComBSTR 

    STDMETHOD(SetString)(BSTR str); 
}; 

STDMETHODIMP CParamClass::SetString(BSTR str) 
{ 
    m_str = str; 
    return S_OK; 
} 
+0

谢谢!有效! – Kamil

+1

这只有在没有编组时才会起作用,否则'IParamClass *'指针可能指向代理,然后演员将是非法的。 – sharptooth

+0

@sharptooth有什么指导COM对象控制的生命周期? – Kamil