IDispatch::Invoke method参数调用问题

yu549867265 2011-12-26 07:29:32
对IDispatch::Invoke method 不熟悉,照着MSDN上的说明写了这样的调用,无法得到我想要的东西,恳请各位高手指点,在此谢过!!

我想取出IDL文件中Iocls接口下的方法“SI2”的方法的返回值:

SI2 方法定义:
SI2(SHORT BVI2, SHORT* BRI2, SHORT* pVal)


Invoke方法:
......
hr = cls1->QueryInterface(IID_IDispatch, (LPVOID*)&obj); //cls1为指向接口Iocls的指针
DISPPARAMS params;
params.cArgs = 3;
params.cNamedArgs = 3;

if(SUCCEEDED(hr))
{
//因为SI2有三个参数。。
params.rgvarg = new VARIANT[params.cArgs];
params.rgvarg[0].vt = VT_I2 | VT_BYREF;
params.rgvarg[0].llVal = 0;
params.rgvarg[0].vt = VT_I2 | VT_BYREF;
params.rgvarg[0].llVal = 5;
params.rgvarg[1].vt = VT_I2;
params.rgvarg[1].llVal = 5;

VARIANT shortVal;
VariantInit(&shortVal);
DISPID dispid;
OLECHAR FAR* szMember = L"SI2";
hr = obj->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_SYSTEM_DEFAULT, &dispid); //hr = S_OK;

hr = obj->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶ms, &shortVal, NULL, NULL); //hr = 0x8002000e Invalid number of parameters.

}
......
请问各位: Invoke参数哪儿处理的不对?
...全文
486 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
yu549867265 2012-01-05
  • 打赏
  • 举报
回复
问题解决,在此谢过大家,是大家给我提醒跟提示后得到的答案:
正确的做法是:
Invoke方法:
......
hr = cls1->QueryInterface(IID_IDispatch, (LPVOID*)&obj); //cls1为指向接口Iocls的指针
DISPID dispid;
OLECHAR FAR* szMember = L"SI2";
hr = obj->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_SYSTEM_DEFAULT, &dispid);

DISPPARAMS params;
params.cArgs = 2;
params.cNamedArgs = 0;

params.rgdispidNamedArgs = NULL;
params.rgvarg = new VARIANT[params.cArgs];
params.rgvarg[1].vt = VT_I2 | VT_BYREF;
SHORT shortVar = 5;
params.rgvarg[1].piVal = &shortVar;
params.rgvarg[0].vt = VT_I2;
params.rgvarg[0].iVal = 5;
VARIANT shortVal;
VariantInit(&shortVal);
EXCEPINFO FAR *pExcepinfo = NULL;
unsigned int FAR *puArgErr = NULL;

hr = obj->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶ms, &shortVal, pExcepinfo, puArgErr);

主要的问题是params里面的参数设置错误,应该是2个参数而不是3个,返回值用pVarResult接收。 引用传进去应该用params.rgvarg[1].piVal...
yu549867265 2012-01-04
  • 打赏
  • 举报
回复
目前我还是没能解决问题,欢迎大家给我提出宝贵的建议!我会及时给分的。
yu549867265 2012-01-04
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 firmbird 的回复:]

应该只有两个参数,返回值是通过Invoke的pVarResult来接收的
[/Quote]
谢谢你的关注,但是这里参数应该是3的。我试着把参数改成2,Invoke调用时直接抛异常了。
我的SI2方法定义是这样的:
SI2(SHORT BVI2, SHORT* BRI2, SHORT* pVal) ‘pVal是一个返回参数

IDL文件中,SI2说明如下:
[id(4), helpstring("method SI2")] HRESULT SI2([in] SHORT BVI2, [in,out] SHORT* BRI2, [out,retval] SHORT* pVal);
firmbird 2012-01-03
  • 打赏
  • 举报
回复
应该只有两个参数,返回值是通过Invoke的pVarResult来接收的
yu549867265 2011-12-27
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 fight_in_dl 的回复:]

params.cNamedArgs = 3;
把3换成0或者1试试,具体含义我忘记了,楼主也可以查一下。
[/Quote]
谢谢你的回复,换成0或者1还是一样的不管用。
我查看了这个参数的说明,但是还是不理解:
http://msdn.microsoft.com/en-us/library/aa912051.aspx

typedef struct FARSTRUCT tagDISPPARAMS {
VARIANTARG FAR* rgvarg;
DISPID FAR* rgdispidNamedArgs;
unsigned int cArgs;
unsigned int cNamedArgs;
} DISPPARAMS;



Members

--------------------------------------------------------------------------------


rgvarg
Array of arguments.

rgdispidNamedArgs
Dispatch identifiers of named arguments.

cArgs
Number of arguments.

cNamedArgs
Number of named arguments.

这里我有三个参数,cArgs = 3 , cNamedArg:命名了的参数数目?我的理解对吗?如果是对的,也是3个。。
战在春秋 2011-12-27
  • 打赏
  • 举报
回复
params.cNamedArgs = 3;
把3换成0或者1试试,具体含义我忘记了,楼主也可以查一下。

yu549867265 2011-12-27
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 fishion 的回复:]

SI2的各参数的属性是什么,in,out,retval
[/Quote]

IDL文件里面SI2的定义:
[id(4), helpstring("method SI2")] HRESULT SI2([in] SHORT BVI2, [in,out] SHORT* BRI2, [out,retval] SHORT* pVal);
fishion 2011-12-27
  • 打赏
  • 举报
回复
SI2的各参数的属性是什么,in,out,retval
yu549867265 2011-12-27
  • 打赏
  • 举报
回复
请路过的高手指点,多谢!!
yu549867265 2011-12-27
  • 打赏
  • 举报
回复
谢谢楼上的两位,我错了。。
但是我改完了debug过了。。问题依旧存在。。

。。。。。。
hr = obj->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶ms, &shortVal, NULL, NULL); //hr = 0x8002000e Invalid number of parameters.
fishion 2011-12-26
  • 打赏
  • 举报
回复
params.rgvarg[0].vt = VT_I2 | VT_BYREF;
params.rgvarg[0].llVal = 0;
params.rgvarg[1].vt = VT_I2 | VT_BYREF;
params.rgvarg[1].llVal = 5;
params.rgvarg[2].vt = VT_I2;
params.rgvarg[2].llVal = 5;

这样
战在春秋 2011-12-26
  • 打赏
  • 举报
回复
params.rgvarg[0].vt = VT_I2 | VT_BYREF;
params.rgvarg[0].llVal = 0;
params.rgvarg[0].vt = VT_I2 | VT_BYREF;
params.rgvarg[0].llVal = 5;
params.rgvarg[1].vt = VT_I2;
params.rgvarg[1].llVal = 5;

三个参数,params.rgvarg的下标应该是从[0]到[2],而不是只有[0]和[1]。
yu549867265 2011-12-26
  • 打赏
  • 举报
回复

补充: 我想得到SI2(SHORT BVI2, SHORT* BRI2, SHORT* pVal)中当BVI2 = 5,*BRI2 = 5时,*pVal的返回值,通过&shortVal取出。

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧