描述:
虽然VC用GetIDsOfNames,Invoke方法有点多事但是对学习COM还是有用的.我只见到过传递一个参数的例子,因此根着感觉写了传两个参数的"BUG"代码:
下列代码中,假设接口的指针ptrILeaf已获取。
如果有vtbl方式调用如下
_bstr_t bstr1("参一"), bstr2("参二");
_bstr_t ret; // 存储返回值
ret = ptrILeaf -> Done(bstr1,bstr2);
将正确的得到ret = 参一参二; (也就是返回bstr1 与 bstr2 的和)
但下面用Invoke方法缺得到 ret = 参二参二 , 没有把参数一的值传进去
似乎执行的是 ret = ptrILeaf -> Done(bstr2,bstr2); 这是为什么?
以下的注释是我对个部分代码的理解,可能我的理解有错误请哥哥姐姐们指正。
谢谢 !!!!
void CTstFlowerDlg::OnButtonInvoke()
{
wchar_t *name = L"Done"; // 存储待查询函数的名字
//--------------- 调用GetIDsOfNames()函数得到DispID --------------------
DISPID dispID; // 存储待查询函数的DispID
ptrILeaf->GetIDsOfNames(IID_NULL, // 必须为IID_NULL
&name , // 一个指向 存储函数名的指针 的指针
1 ,// 函数名的个数
GetUserDefaultLCID(),
&dispID // 返回待查函数的DispID
);
//---------------- 用Invoke()执行对应DispID 的函数 ---------------------
VARIANT ret; // 存贮返回值
VariantInit(&ret); // 初始化VARIANT类型的变量
ret.vt = VT_BSTR; // 指明要存贮的返回值得类型为BSTR
VARIANT var[2];
// 初始化VARIANT类型的变量
::VariantInit(&var[0]);
::VariantInit(&var[1]);
// 指明var[0],var[1]将存贮BSTR类型的变量
var[0].vt=VT_BSTR;
var[1].vt=VT_BSTR;
// 按BSTR类型的方式给数组元素赋值
var[0].bstrVal = _bstr_t("A");
var[1].bstrVal = _bstr_t("B");
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
DISPPARAMS param; // 存储被调函数的参数
param.cNamedArgs = 0; //永远为0
param.rgdispidNamedArgs = NULL; //永远为NULL
param.rgvarg = var; // 用以存储被调函数参数表数组的首地址(VARIANT类型的数组)
param.cArgs = 2 ; // 参数表数组的元素个数
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
ptrILeaf->Invoke(dispID, // 被调用函数的DispID
IID_NULL, // 必须为IID_NULL
GetUserDefaultLCID(),
DISPATCH_METHOD, // 调用方式
¶m, // 存储被调函数的参数的标准结构的地址
&ret, // 存贮被调函数的返回值得VARIANT型指针
NULL,
NULL );
}