2016-03-11 2 views
0

Как this thread, но когда я передать строку в метод, строка в классе ком не так, вот код:Как передать объект класса ATL 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