C++ 如何将ATL com类对象作为参数传递给com
类似,但当我将字符串传递到方法中时,com类中的字符串是错误的,下面是代码: com服务器-com.idl:C++ 如何将ATL com类对象作为参数传递给com,c++,com,atl,C++,Com,Atl,类似,但当我将字符串传递到方法中时,com类中的字符串是错误的,下面是代码: com服务器-com.idl: interface IParamClass : IUnknown { [] HRESULT SetString([in] BSTR str); } interface IMyClass : IUnknown { [] HRESULT PassComClassAsParam([in] IParamClass* parm); } paraclass.cpp class A
interface IParamClass : IUnknown
{
[] HRESULT SetString([in] BSTR str);
}
interface IMyClass : IUnknown
{
[] HRESULT PassComClassAsParam([in] IParamClass* parm);
}
paraclass.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
...
}
客户:
您必须在此处复制字符串参数,因为您无法控制值的生存期:
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;
}
类ATL\u NO\u VTABLE CParamClass:。。。
{
...
公众:
CComBSTR m_str;//您必须在此处复制字符串参数,因为您无法控制值的生存期:
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;
}
类ATL\u NO\u VTABLE CParamClass:。。。
{
...
公众:
CComBSTR m_str;//这仅在没有编组的情况下有效,否则,IParamClass*
指针可能指向代理,则强制转换将是非法的。@sharptooth com对象控件的生命周期是否有任何指南?@Roman您能告诉我为什么以前的BSTR m_str会被释放?为什么m_str在它被释放时会释放以前的字符串新值?@Kamil在本例中是关于BSTR的生存期。BSTR是一个“In”参数,因此调用方只能在调用期间保持BSTR处于活动状态。一旦调用完成,调用方可以自由释放BSTR。因此,如果被调用方在调用后需要BSTR,则必须复制它。在早期代码中,您只有一个原始指针,在调用后该指针会变小。此答案中建议使用新代码深度复制BSTR,以便调用者释放其副本对被调用者没有影响。这只在没有编组的情况下才有效,否则IParamClass*
指针可能指向代理,然后强制转换将是非法的。@sharptooth有没有com对象控件的生存期指南?@Roman你能告诉我为什么以前的BSTR是非法的吗m_str已释放?为什么m_str在分配新值时会释放以前的字符串?@Kamil在本例中是关于BSTR生存期的。BSTR是一个“In”参数,因此调用方只能在调用期间保持BSTR处于活动状态。一旦调用完成,调用方可以自由释放BSTR。因此,如果被调用方在调用后需要BSTR,则必须复制它。在早期代码中,您只有一个原始指针,在调用后该指针会变小。此答案中建议使用新代码深度复制BSTR,以便调用方释放其副本对被调用方没有影响。