MFC读取excel文件程序,在release模式下正常读取,但在debug模式编译没问题,运行就关闭,求高手!
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC读取excel文件程序,在release模式下正常读取,但在debug模式编译没问题,运行就关闭,求高手!相关的知识,希望对你有一定的参考价值。
这是错误现象
我的系统是win7 64位,vc++6.0。
程序很简单,就是打开一个EXCEL文件,
编译无错无警告,就是生产EXE后点击打开就出现上面的错误。
于是把生产的exe考到我的xp虚拟机内运行是能够打开文件的,我又回到win7换为Release模式也可以正常打开文件。
用断点调试发现objApp.CreateDispatch("Excel.Application")运行这个就内存泄露,
下面是xp虚拟机内运行效果
下面是用 Release模式运行效果
好奇怪啊,不用Debug后面的调试没法进行,加之在下本为业余,所以请教高手帮忙了。
打开按钮的代码如下:
void CTestDlg::OnOpen()
_Application objApp;
Workbooks objBooks;
COleVariant VOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
if(!objApp.CreateDispatch("Excel.Application")) //错误在这里产生
AfxMessageBox("无法启动Excel程序,请正确安装!"); return;
objApp.m_bAutoRelease = TRUE;
objApp.SetVisible(TRUE);
objApp.SetUserControl(TRUE);
LPDISPATCH pWkBooks = objApp.GetWorkbooks();
objBooks.AttachDispatch(pWkBooks,TRUE);
char CurrentProgramPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH,CurrentProgramPath);
CString ExcelFilePathName = CurrentProgramPath;
ExcelFilePathName += \\Data.xls;
objBooks.Open(ExcelFilePathName, VOptional, _variant_t(true), VOptional, VOptional, VOptional, VOptional, VOptional,VOptional, VOptional, VOptional, VOptional, VOptional,VOptional,VOptional);
刚刚试了,还是不行啊!
追答那你直接在生成的 exe 上右键 以管理员权限运行 试试呢。
追问试了,还是不行。刚刚我在xp虚拟机上装了VC,把工程全部复制过去,结果在Debug和Release模式下一切OK,这个win7用起来还真头大啊。
追答一般都是权限问题导致的,因为你是动态创建对象,win7对这个要求权限控制的比较严格。
其实操作xls还有一种办法就似乎把xls看做是数据库,用 ado 来连接读写。这个应该就没你说的的问题了。好用的ado库可以参见:www.vckbase.com/index.php/wv/469.html
这就是之前用ADO操作的结果,数据库不对,也装不了,没办法才改成现在的方式,至少一半是成功的。
sql语句中表名要加中括号和$,类似这样 [exceldemo$]
本回答被提问者采纳 参考技术B tryif(!objApp.CreateDispatch("Excel.Application")) //错误在这里产生
AfxMessageBox("无法启动Excel程序,请正确安装!");
return;
catch(...)
AfxMessageBox("启动Excel程序出了点问题!");
另外,检查你要打开的excel文件是不是已经打开?还有,这类程序如果你打开了某个excel文件在程序中没有关闭,那么这个excel文件就会一直是打开的,很麻烦。程序意外中断excel文件也不会关闭,最糟糕的情况只有重启。 参考技术C CoInitialize(NULL);
if(!objApp.CreateDispatch("Excel.Application")) //错误在这里产生
AfxMessageBox("无法启动Excel程序,请正确安装!");
return;
...
退出后
CoUninitialize();
mfc 中的 DLL 函数出错
【中文标题】mfc 中的 DLL 函数出错【英文标题】:Error with DLL functions in mfc 【发布时间】:2015-01-02 06:23:42 【问题描述】:我做了一个小应用程序,我在应用程序类的 Init 实例中加载了一个 DLL。下面提到的代码运行正常,但在发布模式下它正在崩溃。我使用 Visual Studio,DLL 位于应用程序的 Debug 和 Release 文件夹中。
typedef char BufType[4095];
typedef int (*QuickLicenseRT)(BufType);
BufType Buf;
QuickLicenseRT pQuickLicense;
HINSTANCE QL_Lib;
char* Message;
int i, BufSize;
BOOL CDemo::InitInstance()
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
QL_Lib = LoadLibrary(_T("QuickLicenseRuntime.dll"));
pQuickLicense = (QuickLicenseRT)GetProcAddress(QL_Lib, "QuickLicenseRT");
Message = "ABC";
BufSize = strlen(Message);
for(i=0; i<BufSize; i++)
Buf[i]= Message[i];
Buf[BufSize] = 0;
MessageBox(NULL, _T("before pQuickLicense (Buf)"), _T("Message"), MB_OK);
(pQuickLicense)(Buf); // here it is crashing
MessageBox(NULL, _T("after pQuickLicense (Buf)"), _T("Message"), MB_OK);
ResponseMessage = Buf;
return TRUE;
我在一些语句之后放置了一些消息框。我注意到在 (pQuickLicense)(Buf) 处,它正在崩溃。加载 QuickLicenseRuntime.dll 后,我得到了函数的地址。我不明白哪里错了。
谢谢
【问题讨论】:
总是检查你的LoadLibrary()
GetProcAddress()
调用的结果——如果它们不是NULL,那么崩溃是在QuickLicenseRT()
逻辑(在DLL中),你可能需要构建一些可选的诊断日志以查看崩溃的位置;调试版本和发布版本之间的主要区别之一是指针初始化...
【参考方案1】:
Buf[BufSize] = 0;
已经写出 Buf 区域,理论上会损坏 pQuickLicense —— 实际上它不应该因为填充而造成伤害。 Buf[BufSize-1] = '\0';
会更合适。
您还可以修改 typedef int (*QuickLicenseRT)(BufType);
以定义调用约定,即 __cdecl 或 FAR PASCAL。使用错误的调用约定可能会损坏您的数据内存。
一般来说,您的编程风格可能会受益于考虑一些有关 C++ 的基本知识,即 Kerningham 和 Ritchie “用 C 编程”。
【讨论】:
鉴于代码逻辑,Buf[BufSize-1]='\0'
将错误地截断字符串。不管怎样,由于BufSize
是从不相关的数据推导出来的,因此使用BufSize
或BufSize-1
作为索引同样是错误的。动态大小的数组,如std::vector
将解决所有问题。然而,缺少的调用约定将是崩溃的主要候选者。函数指针类型应该可以通过库附带的头文件获得。
@Girish:您使用 strlen 而不是 sizeof 编辑了问题中的代码,让我困惑了一分钟。新代码Message = "ABC"; BufSize = strlen(Message); Buf[BufSize] = 0;
只是在它已经存在的地方写入一个 '\0' 字符,因为strlen()
只是对字符进行计数,直到找到一个空字符。如果你真的需要初始化缓冲区,try Buf[0] = 0 or memset(Buf, 0, sizeof(Buf));
。如果只想复制字符串,单行strcpy(Buf, Message);
就足够了。
这是不正确的。复制字符的循环具有i<BufSize
的终止条件,实质上是在零终止符之前 停止。因此Buf[BufSize]=0
是强制性的。显然,strcpy
更易于使用,因为它已经处理了零终止符。不过,它也无法避免缓冲区溢出。
@IInspectable:假设在 Buf[3] 处为空字符,您错过了从 strlen(Buf) 派生的 BufSize (3)。
我很清楚 source 字符串有一个零终止符。但是,缓冲区副本没有,Buf[BufSize]=0
是强制性的。 Buf
是一个本地对象,因此不是零初始化的。这不是具有静态存储持续时间的对象(将被零初始化)。编辑:我假设 Buf
是一个本地对象。它不是(无论出于何种原因),也不需要Buf[BufSize]=0
。以上是关于MFC读取excel文件程序,在release模式下正常读取,但在debug模式编译没问题,运行就关闭,求高手!的主要内容,如果未能解决你的问题,请参考以下文章
MFC编写的程序,release时出错,希望高手能够指点!!!
VC/MFC动态库Debug版本下正常,Release版本下错误