c – 为什么CoUninitialize会在退出时导致错误?
作者:互联网
我正在使用C应用程序从Excel文件中读取一些数据.我有它的工作,但我对一部分感到困惑.这是代码(简化为只读取第一个单元格).
//Mostly copied from http://www.codeproject.com/KB/wtl/WTLExcel.aspx
#import "c:\Program Files\Common Files\Microsoft Shared\OFFICE11\MSO.DLL"
#import "c:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
#import "C:\Program Files\Microsoft Office\Office11\excel.exe" rename ("DialogBox","ExcelDialogBox") rename("RGB","ExcelRGB") rename("CopyFile", "ExcelCopyFile") rename("ReplaceText", "ExcelReplaceText") exclude("IFont", "IPicture")
_variant_t varOption((long) DISP_E_PARAMNOTFOUND, VT_ERROR);
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwCoInit = 0;
CoInitializeEx(NULL, dwCoInit);
Excel::_ApplicationPtr pExcel;
pExcel.CreateInstance(_T("Excel.Application"));
Excel::_WorkbookPtr pBook;
pBook = pExcel->Workbooks->Open("c:\\test.xls", varOption, varOption, varOption, varOption, varOption, varOption, varOption, varOption, varOption, varOption, varOption, varOption);
Excel::_WorksheetPtr pSheet = pBook->Sheets->Item[1];
Excel::RangePtr pRange = pSheet->GetRange(_bstr_t(_T("A1")));
_variant_t vItem = pRange->Value2;
printf(_bstr_t(vItem.bstrVal));
pBook->Close(VARIANT_FALSE);
pExcel->Quit();
//CoUninitialize();
return 0;
}
我不得不评论对CoUninitialize的调用以使程序正常工作.取消注释CoUninitialize时,我在程序退出时在comip.h中的_Release函数中获得访问冲突.
这是来自comip.h的代码,它的价值.
void _Release() throw()
{
if (m_pInterface != NULL) {
m_pInterface->Release();
}
}
我对COM编程不是很有经验,所以可能有一些我不知道的东西.
>为什么调用CoUninitialize会导致异常?
>不调用CoUninitialize有什么后果?
>我在这里完全错了吗?
解决方法:
你遇到的问题是范围之一.简短的回答是将CoInit和CoUninit移动到Ptrs的外部范围.例如:
//Mostly copied from http://www.codeproject.com/KB/wtl/WTLExcel.aspx
#import "c:\Program Files\Common Files\Microsoft Shared\OFFICE11\MSO.DLL"
#import "c:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
#import "C:\Program Files\Microsoft Office\Office11\excel.exe" rename ("DialogBox","ExcelDialogBox") rename("RGB","ExcelRGB") rename("CopyFile", "ExcelCopyFile") rename("ReplaceText", "ExcelReplaceText") exclude("IFont", "IPicture")
_variant_t varOption((long) DISP_E_PARAMNOTFOUND, VT_ERROR);
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwCoInit = 0;
CoInitializeEx(NULL, dwCoInit);
{
Excel::_ApplicationPtr pExcel;
pExcel.CreateInstance(_T("Excel.Application"));
Excel::_WorkbookPtr pBook;
pBook = pExcel->Workbooks->Open("c:\\test.xls", varOption, varOption, varOption, varOption, varOption, varOption, varOption, varOption, varOption, varOption, varOption, varOption);
Excel::_WorksheetPtr pSheet = pBook->Sheets->Item[1];
Excel::RangePtr pRange = pSheet->GetRange(_bstr_t(_T("A1")));
_variant_t vItem = pRange->Value2;
printf(_bstr_t(vItem.bstrVal));
pBook->Close(VARIANT_FALSE);
pExcel->Quit();
}
CoUninitialize();
return 0;
}
更长的答案是在从main退出时调用Ptrs析构函数(调用Release).这是在CoUnit之后,它基本上关闭了你的应用程序和COM对象之间的通信通道.
不调用CoUnit有什么后果?对于短期进程中的COM服务器,确实没有任何负面后果.
标签:access-violation,c,excel,com 来源: https://codeday.me/bug/20191005/1856022.html