我定义了一个COM接口IXManageInfoBase,并有对应的事件接口DXManageInfoBaseEvents
interface IXManageInfoBase : IUnknown{
typedef struct _CLIENT_INFO{
DWORD dwIpAddr;
USHORT usPort;
[string] wchar_t* pwszMAC;
[string] wchar_t* pwszComputerName;
}CLIENT_INFO; [, helpstring("method GetXXXX")] HRESULT GetXXXX([in] CLIENT_INFO* pClient);
};library sdcsrvmLib
{
......
dispinterface DXManageInfoBaseEvents
{
properties:
methods:
[id(1), helpstring("method OnClientChanged")] HRESULT OnClientChanged([in] CLIENT_INFO* pclient);
};
.......
coclass XManageInfoBase
{
[default] interface IXManageInfoBase;
[default, source] dispinterface DXManageInfoBaseEvents;
};
};GetXXXX和OnClientChanged的函数参数类型都是CLIENT_INFO*
GetXXXX函数调用正常,
但事件接口中的OnClientChanged函数中使用CLIENT_INFO*时碰到几个问题:
1, 以下代码是MFC自动为事件接口对象生成的代码,但在编译的时候,编译器警告说会把avarParams[0] = pclient;强制转为BOOL型
2. 我把代码改为如下: avarParams[0] = (BYTE*)pclient; 编译没有警告了,但在客户端被传递过去的只是一个字节
请问我该如何修改才能把CLIENT_INFO的完整结构传递过去?
#pragma once
template<class T>
class CProxyDXManageInfoBaseEvents :
public IConnectionPointImpl<T, &__uuidof(DXManageInfoBaseEvents)>
{
public:
HRESULT Fire_OnClientChanged( SDC_EVENT_ACTION sea, SDC_CLIENT_INFO * pclient)
{
HRESULT hr = S_OK;
T * pThis = static_cast<T *>(this);
int cConnections = m_vec.GetSize(); for (int iConnection = 0; iConnection < cConnections; iConnection++)
{
pThis->Lock();
CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
pThis->Unlock(); IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p); if (pConnection)
{
CComVariant avarParams[2];
avarParams[1] = sea;
avarParams[0] = pclient;
CComVariant varResult; DISPPARAMS params = { avarParams, NULL, 2, 0 };
hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);
}
}
return hr;
}
};
interface IXManageInfoBase : IUnknown{
typedef struct _CLIENT_INFO{
DWORD dwIpAddr;
USHORT usPort;
[string] wchar_t* pwszMAC;
[string] wchar_t* pwszComputerName;
}CLIENT_INFO; [, helpstring("method GetXXXX")] HRESULT GetXXXX([in] CLIENT_INFO* pClient);
};library sdcsrvmLib
{
......
dispinterface DXManageInfoBaseEvents
{
properties:
methods:
[id(1), helpstring("method OnClientChanged")] HRESULT OnClientChanged([in] CLIENT_INFO* pclient);
};
.......
coclass XManageInfoBase
{
[default] interface IXManageInfoBase;
[default, source] dispinterface DXManageInfoBaseEvents;
};
};GetXXXX和OnClientChanged的函数参数类型都是CLIENT_INFO*
GetXXXX函数调用正常,
但事件接口中的OnClientChanged函数中使用CLIENT_INFO*时碰到几个问题:
1, 以下代码是MFC自动为事件接口对象生成的代码,但在编译的时候,编译器警告说会把avarParams[0] = pclient;强制转为BOOL型
2. 我把代码改为如下: avarParams[0] = (BYTE*)pclient; 编译没有警告了,但在客户端被传递过去的只是一个字节
请问我该如何修改才能把CLIENT_INFO的完整结构传递过去?
#pragma once
template<class T>
class CProxyDXManageInfoBaseEvents :
public IConnectionPointImpl<T, &__uuidof(DXManageInfoBaseEvents)>
{
public:
HRESULT Fire_OnClientChanged( SDC_EVENT_ACTION sea, SDC_CLIENT_INFO * pclient)
{
HRESULT hr = S_OK;
T * pThis = static_cast<T *>(this);
int cConnections = m_vec.GetSize(); for (int iConnection = 0; iConnection < cConnections; iConnection++)
{
pThis->Lock();
CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
pThis->Unlock(); IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p); if (pConnection)
{
CComVariant avarParams[2];
avarParams[1] = sea;
avarParams[0] = pclient;
CComVariant varResult; DISPPARAMS params = { avarParams, NULL, 2, 0 };
hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);
}
}
return hr;
}
};
编译时顺利通过的,而且事件函数触发顺利,但就是传递过去的参数不对
COM客户端调用COM服务器的接口这样写没问题,但事件回调这样写就有问题,不知道为什么?再重贴一边后一部分#pragma once
template<class T>
class CProxyDXManageInfoBaseEvents :
public IConnectionPointImpl<T, &__uuidof(DXManageInfoBaseEvents)>
{
public:
HRESULT Fire_OnClientChanged(SDC_CLIENT_INFO * pclient)
{
HRESULT hr = S_OK;
T * pThis = static_cast<T *>(this);
int cConnections = m_vec.GetSize(); for (int iConnection = 0; iConnection < cConnections; iConnection++)
{
pThis->Lock();
CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
pThis->Unlock(); IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p); if (pConnection)
{
CComVariant avarParams[1];
avarParams[0] = pclient;
CComVariant varResult; DISPPARAMS params = { avarParams, NULL, 1, 0 };
hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);
}
}
return hr;
}
};
由于你传递的指针是用户类型指针,当连接点客户端被调用时,VARIANT参数没有正确地转换成你需要的指针类型,后果是难以预料的。
谢谢, VARIANT好像是被强制转换成了BOOL型,
avarParams[0] = (BYTE*)pclient; 将其强制转化为BYTE*型,还是不对,
问题是看了下CComVariant的赋值函数,只有对应几个基本类型的,我无法写成avarParams[0] = (CLIENT_INFO*)pclient,编译通不过的
请问CComVariant中的类型应该设成什么类型才能正确传递参数。To: yjgx007
请问“包装在Variant变量中传递.”是什么意思,能不能说的详细点,谢谢。
{
};传递时,
CLIENT_INFO ci;
VARIANT var;
var.vt = VT_DISPATCH;
var.pdispVal= &ci;接口定义:[id(1), helpstring("method OnClientChanged")] HRESULT OnClientChanged([in] VARIANT* pclient);
用非标准的COM接口作参数只能产生未遇料到的错误 .
pclient是我自己定义的一个结构指针,
不清楚是服务器端还是客户端把数据给截留了,
只是奇怪的是如果是一个普通接口的方法的话,参数传递是没问题的,搞不清楚了
不过采用了一个笨办法,先发问题给对应过去了,
感谢楼上各位的帮忙了。~~