C++ 如何将ATL com类对象作为参数传递给com

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

类似,但当我将字符串传递到方法中时,com类中的字符串是错误的,下面是代码:

com服务器-com.idl:

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,以便调用方释放其副本对被调用方没有影响。