我目前正在尝试使用COM调用一个软件的ActiveX函数。下面是函数声明:
[
id(0xa),
helpcontext(0)
]
HRESULT MAIN_GetVersion (
[out] short* nStatus,
[out] BSTR* szStatusMsg,
[out] BSTR* szVersion
);
下面是我的做法:
short errorCode = 0;
BSTR errorMessageBSTR = SysAllocString(L"test");
BSTR versionBSTR = SysAllocString(L"test");
VARIANT result;
DISPPARAMS params = {NULL, NULL, 0, 0};
VARIANTARG args[3];
//First argument : Short*
VariantInit(&args[0]);
args[0].vt = VT_I2 | VT_BYREF;
args[0].piVal = &errorCode;
//Second argument : BSTR*
VariantInit(&args[1]);
args[1].vt = VT_BSTR | VT_BYREF;
args[1].pbstrVal = &errorMessageBSTR;
//Third argument : BSTR*
VariantInit(&args[2]);
args[2].vt = VT_BSTR | VT_BYREF;
args[2].pbstrVal = &versionBSTR;
params.rgvarg = args;
params.cArgs = 3;
DISPID dispID;
char szName[200];
// Convert down to ANSI
wchar functionName[] = L"MAIN_GetVersion";
wchar_t* functionNamePtr = functionName;
WideCharToMultiByte(CP_ACP, 0, functionName, -1, szName, 256, NULL, NULL);
CheckHResult(App.pdispVal->GetIDsOfNames(IID_NULL, &functionNamePtr, 1, LOCALE_USER_DEFAULT, &dispID) ,szName , dispID);
CheckHResult(App.pdispVal->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶ms, &result, NULL, NULL), szName , dispID);
/*
return :
DISP_E_TYPEMISMATCH
One or more of the arguments could not be coerced. The index of the first parameter with the incorrect type within rgvarg is returned in puArgErr.
*/
由于某种原因,这段代码不能工作,并返回disp_e_typemismatch。由于其他原因,如果我将所有变量vartype'semphasized文本设置为VT_EMPTY,它可以工作,但是我没有从结果变量返回任何东西。
有没有可能我试图驱动的软件的activeX实现是错误的?我是不是做错了什么?!
当构建DISPPARAMS来设置一些args时,您需要按照调用的相反顺序对它们进行排序。在我的情况下:
//First argument : Short*
VariantInit(&args[2]);
args[2].vt = VT_I2 | VT_BYREF;
args[2].piVal = &errorCode;
//Second argument : BSTR*
VariantInit(&args[1]);
args[1].vt = VT_BSTR | VT_BYREF;
args[1].pbstrVal = &errorMessageBSTR;
//Third argument : BSTR*
VariantInit(&args[0]);
args[0].vt = VT_BSTR | VT_BYREF;
args[0].pbstrVal = &versionBSTR;
short是我的变体数组的最后一个变体。