【发布时间】:2015-06-03 07:10:37
【问题描述】:
我正在编写一个程序来解析 Word 文档并使用 OLE 自动化(我猜是非 MFC 方式)将数据导出到 Excel 工作簿。在 Debug 中工作正常,在 Release 中则不然(特别是在启用优化的情况下)。错误是IDispatch::Invoke调用失败,具体是:
0x80020004 DISP_E_PARAMNOTFOUND Parameter not found
我检查了 StackOverflow 的一些建议,主要的似乎是未初始化的变量。这可能是正在发生的事情,但我仍然不明白这个具体案例。我已将其缩小到我的程序Automation::Dispatch::Invoke 中的一个函数,它负责最终调用IDispatch::Invoke。传递给Automation::Dispatch::Invoke 的参数是正确的,所以问题出在它的代码中。
查看我改编的基本代码(来自 MSDN),我能够让它工作并缩小确切的问题范围。下面显示了不起作用的代码,但 cmets 表示我移动以使其正常工作的行(查找带有 <--- Problem line 注释的 2 行)。在调试模式下,这条线的位置无关紧要,它可以在任何一个位置工作。
我的问题是,这能解决什么问题,为什么一开始会出现问题?谢谢,如果我能把问题说得更清楚,请告诉我。
HRESULT Automation::Dispatch::Invoke(int cmd, std::string name, std::vector<VARIANT> values)
{
USES_CONVERSION;
HRESULT result;
/* Get DISPID for name passed */
DISPID dispID;
LPOLESTR nameOle=A2OLE(name.c_str());
result=pObjectInt->GetIDsOfNames(IID_NULL, &nameOle, 1, LOCALE_USER_DEFAULT, &dispID);
if (FAILED(result)) {
return result;
}
/* Reverse elements in values vector so they are invoked in the correct order */
std::reverse(values.begin(), values.end());
/* Allocate memory for object values */
VARIANT *pValues=new VARIANT[values.size() + 1];
for (unsigned int i=0; i < values.size(); ++i) {
pValues[i]=values[i];
}
/* Build DISPPARAMS */
DISPPARAMS dispParams= {NULL, NULL, 0, 0};
/* DISPID dispidNamed=DISPID_PROPERTYPUT; <--- PROBLEM LINE moved here makes it work */
dispParams.cArgs=values.size();
dispParams.rgvarg=pValues;
/* Handle special-case for property-puts */
if (cmd==DISPATCH_PROPERTYPUT) {
DISPID dispidNamed=DISPID_PROPERTYPUT; /* <--- PROBLEM LINE here */
dispParams.cNamedArgs=1;
dispParams.rgdispidNamedArgs=&dispidNamed;
}
/* Make the call */
if (cmd==DISPATCH_METHOD || cmd==DISPATCH_PROPERTYPUT) {
result=pObjectInt->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, cmd, &dispParams, NULL, NULL, NULL);
}
else {
VariantInit(&objectData);
result=pObjectInt->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, cmd, &dispParams, &objectData, NULL, NULL);
}
delete[] pValues;
return result;
}
【问题讨论】:
-
查看你在被破坏的块中寻址 (
&dispidNamed) 的变量的范围(强调within)。在该块之外它不再存在。因此,您将dispParams发送到一个很好地加载了一个悬空指针的 API 调用。 -
哦,哇,这很明显......像往常一样,在愚蠢的事情上浪费了大量时间。
-
更真实的说法是从未有人说过软件工程师的生活。祝你好运。
标签: c++ optimization visual-studio-2013 ole office-automation