【问题标题】:How to pass ATL com class object as paramater to COM如何将 ATL com 类对象作为参数传递给 COM
【发布时间】:2016-06-26 08:10:54
【问题描述】:

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

com 服务器 - Com.idl:

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

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

参数类.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);

【问题讨论】:

    标签: c++ com atl


    【解决方案1】:

    您必须在此处复制字符串参数,因为您无法控制值的生命周期:

    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;
    }
    

    【讨论】:

    • 这只有在没有编组的情况下才有效,否则IParamClass* 指针可能指向代理,然后强制转换将是非法的。
    • @sharptooth 有没有关于 com 对象控制生命周期的指南?
    • @Roman 你能告诉我为什么之前的 BSTR m_str 被释放了吗?
    • 为什么 m_str 在分配新值时会释放以前的字符串?
    • @Kamil 在这种情况下,它是关于 BSTR 的生命周期。 BSTR 是一个“in”参数,因此调用者必须只在调用期间保持 BSTR 处于活动状态。一旦调用完成,调用者就可以释放 BSTR。因此,如果被调用者在调用后需要 BSTR,那么它必须复制它。在您的早期代码中,您只有一个原始指针,该指针在调用后会变成 dandling。此答案中建议的新代码深度复制 BSTR,因此调用者释放其副本对被调用者没有任何影响。
    猜你喜欢
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 2012-09-12
    • 2012-08-29
    • 1970-01-01
    • 2012-02-25
    相关资源
    最近更新 更多