为什么CoUninitialize在退出时会导致错误? [英] Why does CoUninitialize cause an error on exit?

查看:1166
本文介绍了为什么CoUninitialize在退出时会导致错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用C ++应用程序从Excel文件读取一些数据。我有它的工作,但我困惑了一部分。这里是代码(简化为只读第一个单元格)。

  //大多从http://www.codeproject复制。 com / KB / wtl / WTLExcel.aspx 

#importc:\Program Files \Common Files \Microsoft Shared\OF​​FICE11\MSO.DLL
#import c:\Program Files \Common Files \Microsoft Shared\VBA\VBA6\VBE6EXT.OLB
#importC:\Program Files \ Microsoft Office \Office11 \excel。 exerename(DialogBox,ExcelDialogBox)rename(RGB,ExcelRGB)rename(CopyFile,ExcelCopyFile)rename(ReplaceText,ExcelReplaceText)exclude )

_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->打开(c:\\test.xls,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->关闭(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会导致异常?



  1. 不调用CoUninitialize会有什么后果?


  2. >



解决方案

您遇到的问题是范围之一。简短的答案是将CoInit和CoUninit从Ptrs移动到外部范围。例如:

  //大部分复制自http://www.codeproject.com/KB/wtl/WTLExcel.aspx 

#importc:\Program Files \Common Files \Microsoft Shared\OF​​FICE11\MSO.DLL
#importc:\Program Files \Common Files \Microsoft Shared\VBA\VBA6\VBE6EXT.OLB
#importC:\Program Files\ Microsoft Office \Office11\excel.exerename(DialogBox,ExcelDialogBox )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->打开(c:\\test.xls,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->关闭(VARIANT_FALSE);
pExcel-> Quit();
}
CoUninitialize();
return 0;
}



更长的答案是Ptrs析构函数从主要出口。这是CoUnit后,基本上,关闭你的应用程序和COM对象之间的通信渠道。



不调用CoUnit的后果是什么?对于短期在进程COM服务器,真的没有任何负面后果。


I'm working on a C++ application to read some data from an Excel file. I've got it working, but I'm confused about one part. Here's the code (simplified to read only the first cell).

//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;
}

I had to comment out the call to CoUninitialize for the program to work. When CoUninitialize is uncommented, I get an access violation in the _Release function in comip.h on program exit.

Here's the code from comip.h, for what it's worth.

void _Release() throw()
{
    if (m_pInterface != NULL) {
        m_pInterface->Release();
    }
}

I'm not very experienced with COM programming, so there's probably something obvious I'm missing.

  1. Why does the call to CoUninitialize cause an exception?

  2. What are the consequences of not calling CoUninitialize?

  3. Am I doing something completely wrong here?

解决方案

The problem you are having is one of scope. The short answer is to move the CoInit and CoUninit into an outer scope from the Ptrs. For example:

//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;
}

The longer answer is that the Ptrs destructors (which calls Release) are being called on exit from main. This is after CoUnit which, basically, shuts down the communication channel between your app and the COM object.

What are the consequences of not calling CoUnit? For short lived in-process COM servers, there really isn't any negative consequence.

这篇关于为什么CoUninitialize在退出时会导致错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆