如何使用IDispatch.Invoke调用接收浮点值的函数?

我无法使用IDispatch.Invoke调用具有浮点参数和浮点结果的函数。

这是一个最小的复制:

 #include <atlbase.h> #include <comutil.h> int main(int argc, char* argv[]) { CoInitialize(NULL); CComPtr<IDispatch> wordapp; if (SUCCEEDED(wordapp.CoCreateInstance(L"Word.Application", NULL, CLSCTX_LOCAL_SERVER))) { CComVariant result; CComVariant centimeters((float)2.0); CComVariant retval = wordapp.Invoke1(L"CentimetersToPoints", &centimeters, &result); } return 0; } 

我正在使用ATL CComPtr使事情更清洁。 但是这是IDispatch.Invoke的一个非常宽松的包装。

当我运行这个,调用Invoke1失败并返回E_FAIL

我怀疑这个问题与使用浮点参数和/或返回值有关。 如果我调用一个不使用这些值的函数,调用将成功:

 CComVariant retval = wordapp.Invoke0(L"ProductCode", &result); 

我注意到,如果我从VBS或从PowerShell调用函数,它会成功。 我假设他们都使用迟来的IDispatch ,所以这将表明,我正在尝试是至less有可能的。

那么,如何使用IDispatch来调用这个函数呢?

那么,这是一个头痛的人。 这个“方法”的文档是非常误导性的,这不是一个方法。 它的行为更像一个索引属性,需要DISPATCH_METHOD | DISPATCH_PROPERTYGET标志。 CComPtr不支持,你需要手动旋转。 此代码工作:

  CComVariant result; CComVariant centimeters((float)2.0); DISPID dispid; LPOLESTR name = L"CentimetersToPoints"; HRESULT hr = wordapp->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid); assert(SUCCEEDED(hr)); DISPPARAMS dispparams = { &centimeters, NULL, 1, 0}; hr = wordapp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD | DISPATCH_PROPERTYGET, &dispparams, &result, nullptr, nullptr); assert(SUCCEEDED(hr));