AfxOleInit()第二次调用就报错

jimycool 2014-04-17 12:25:05
我写了个封装对Excel操作的类,在类构造的时候是这样
CMyExcel::CMyExcel()
if (!AfxOleInit())
{
AfxMessageBox("初始化COM失败");
}

if (!app.CreateDispatch("Excel.Application"))
{
AfxMessageBox("无法启动excel");
}

app.SetVisible(FALSE);
app.SetUserControl(TRUE);

然后我在调用的时候,如果CMyExcel m_excel;声明为成员变量时,在自定义线程中调用操作Excel的函数时就出现异常报错
但是如果把CMyExcel m_excel;声明为局部变量时,就会每调用一次,上面的AfxOleInit())就会被调用一次,而第二次调用的时候就会报错
这两种情况都是怎么回事呢,怎么解决呢
...全文
329 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
jimycool 2014-04-18
  • 打赏
  • 举报
回复
引用 21 楼 CodeMadman 的回复:
AfxOleInit()只支持单线程,所以采用成员变量调用Excel会出现问题。多线程访问excel请采用 HRESULT CoInitializeEx( void * pvReserved, DWORD dwCoInit);具体参见msdn
确实是这样,用CoInitializeEx就可以了,无论是作为成员还是写在函数内部都可以
Yanortun 2014-04-18
  • 打赏
  • 举报
回复
AfxOleInit()只支持单线程,所以采用成员变量调用Excel会出现问题。多线程访问excel请采用 HRESULT CoInitializeEx( void * pvReserved, DWORD dwCoInit);具体参见msdn
jimycool 2014-04-18
  • 打赏
  • 举报
回复
引用 19 楼 schlafenhamster 的回复:
initole.cpp里面 CWinThread* pThread; pThread = AfxGetThread(); ASSERT(pThread); 这里的断言出错 是不是 Excel 界面 不存在 ?
也没有什么界面啊,都是通过那个类去操作Excel的 不知道这里的pThread到底是指什么
schlafenhamster 2014-04-18
  • 打赏
  • 举报
回复
initole.cpp里面 CWinThread* pThread; pThread = AfxGetThread(); ASSERT(pThread); 这里的断言出错 是不是 Excel 界面 不存在 ?
jimycool 2014-04-18
  • 打赏
  • 举报
回复
但是如果不是通过线程去调用的话就一切正常,操作Excel读写的什么的都没有问题
jimycool 2014-04-18
  • 打赏
  • 举报
回复
引用 14 楼 schlafenhamster 的回复:
我就不知道了,请高手帮助.
不能不知道啊,再帮我想想 不知道是不是跟初始化与调用不在一个线程的关系 如果把CMyExcel m_excel;放到函数里面一起接受线程调用就会变成另外一个错误,就是上面讲过的afxole()异常, 如果CMyExcel m_excel;作为成员在线程启动前就实例化,然后线程调用时就会m_excel.CreateExcelFile();出现异常
kuankuan_qiao 2014-04-18
  • 打赏
  • 举报
回复
试试这个函数
CoUninitialize
schlafenhamster 2014-04-18
  • 打赏
  • 举报
回复
我就不知道了,请高手帮助.
jimycool 2014-04-18
  • 打赏
  • 举报
回复
非常感谢各位大神帮我解决这个问题,特别是schlafenhamster , CodeMadman ,谢谢
schlafenhamster 2014-04-17
  • 打赏
  • 举报
回复
static BOOL m_bOleInit; CMyExcel::CMyExcel() if(!m_bOleInit) m_bOleInit=AfxOleInit();
jimycool 2014-04-17
  • 打赏
  • 举报
回复
引用 12 楼 schlafenhamster 的回复:
LPDISPATCH _Application::GetWorkbooks() { LPDISPATCH result; InvokeHelper(0x23c, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL);//这句报错 return result; } 看看是什么错误。
Tech.exe 中的 0x7510812f 处有未经处理的异常: Microsoft C++ 异常: 内存位置 0x0273f0d8 处的 COleException。
schlafenhamster 2014-04-17
  • 打赏
  • 举报
回复
LPDISPATCH _Application::GetWorkbooks() { LPDISPATCH result; InvokeHelper(0x23c, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL);//这句报错 return result; } 看看是什么错误。
jimycool 2014-04-17
  • 打赏
  • 举报
回复
引用 10 楼 schlafenhamster 的回复:
beOle 必须是 static 的, 表示 类变量, 与 实例 个数 无关。 CMyExcel m_excel; 一定要 放 堆栈 里?
beOle 是static 的 另外CMyExcel m_excel;定义为类成员同样会报错 LPDISPATCH _Application::GetWorkbooks() { LPDISPATCH result; InvokeHelper(0x23c, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL);//这句报错 return result; } 查看调用栈, m_excel.CreateExcelFile(); 具体是 BOOL CMyExcel::CreateExcelFile() { COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR); books.AttachDispatch(app.GetWorkbooks()); //这里 book=books.Add(covOptional); sheets=book.GetWorksheets(); sheet=sheets.GetItem(COleVariant((short)1)); return TRUE; }
schlafenhamster 2014-04-17
  • 打赏
  • 举报
回复
beOle 必须是 static 的, 表示 类变量, 与 实例 个数 无关。 CMyExcel m_excel; 一定要 放 堆栈 里?
jimycool 2014-04-17
  • 打赏
  • 举报
回复
引用 8 楼 oyljerry 的回复:
查看返回的错误信息,如果是重复 初始化了,就跳过
重复初始化的已经跳过了 AfxOleInit() 这里第一次初始化就报错了
oyljerry 2014-04-17
  • 打赏
  • 举报
回复
查看返回的错误信息,如果是重复 初始化了,就跳过
jimycool 2014-04-17
  • 打赏
  • 举报
回复
引用 5 楼 schlafenhamster 的回复:
need code of “在自定义线程里调用”
DWORD WINAPI autoProc(LPVOID LPARAM) { ........ sInfo.Format(_T("%s%s%s"),_T("延时"),sStr[2],_T("秒")); engineer->DispToInfo(sInfo); //显示并保存到Excel ................... } void CDlgEngineer::DispToInfo(CString str) { CString sInfo,sOld; sInfo.Format(_T("%s%s%s"),GetCurTime(),_T(" "),str); GetDlgItem(IDC_INFO)->GetWindowTextA(sOld); GetDlgItem(IDC_INFO)->SetWindowTextA(sOld+sInfo+"\r\n"); //显示到标签 CMyExcel m_excel; //Excel操作类 if (!m_excel.OpenExcelFile("D:\\444.xlsx")) { m_excel.CreateExcelFile(); m_excel.SetSheetName(_T("sws"),1); CStringArray header; header.RemoveAll(); header.Add(_T("aaa")); header.Add(_T("bbb")); header.Add(_T("ccc")); m_excel.SetHeader(header); } CStringArray stex; CString tim; tim.Format(_T("%s"),GetCurTime()); stex.RemoveAll(); stex.Add(tim); stex.Add(str); int r,c; m_excel.GetUsedRange(r,c); m_excel.AddRow(stex,r+1); m_excel.SetColor(r+1,2,EXCEL_RED); m_excel.SaveExcelFileAs("D:\\444.xlsx"); m_excel.CloseExcelFile(); } 运行CWinThread* pThread; pThread = AfxGetThread(); ASSERT(pThread); 这里出错 调用堆栈在那个Excel类里面 if (!beOle) { if (!AfxOleInit()) //这句的时候出错,但是不通过线程调用就没问题 { DWORD aa=GetLastError(); AfxMessageBox("初始化COM失败"); } beOle=TRUE; }
worldy 2014-04-17
  • 打赏
  • 举报
回复
每个线程调用一次
schlafenhamster 2014-04-17
  • 打赏
  • 举报
回复
need code of “在自定义线程里调用”
加载更多回复(3)

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧