CSpreadSheet.h 中 SQLGetInstalledDrivers(szBuf,cbBufMax,&cbBufOut) 函数调用崩溃问题

把CSpreadSheet.h 文件从开源社区下载下来,然后进行头文件和实现文件分离。

添加各种头文件,修改各种属性设置,把字符串前添加 _T(),编译通过。

然后测试:

主函数如下:

int _tmain(int argc, _TCHAR* argv[])
{
	CSpreadSheet SS("d:\\name1.xls", "Sheet1", false);        // 此处跟进去

	system("pause");
	return 0;
}

然后转到CSpreadSheet.cpp 文件的初始化函数:

GetExcelDriver();                // 运行到此处,进入GetExcelDriver(),寻找驱动

CSpreadSheet::CSpreadSheet(CString File, CString SheetOrSeparator, bool Backup) :
m_Database(NULL), m_rSheet(NULL), m_sFile(File),
m_dTotalRows(0), m_dTotalColumns(0), m_dCurrentRow(1),
m_bAppend(false), m_bBackup(Backup), m_bTransaction(false)
{
	// Detect whether file is an Excel spreadsheet or a text delimited file
	m_stempString = m_sFile.Right(4);		// 从右边数4个字符
	m_stempString.MakeLower();				// 转换为小写
	if (m_stempString == ".xls") // File is an Excel spreadsheet
	{
		m_bExcel = true;
		m_sSheetName = SheetOrSeparator;
		m_sSeparator = ",;.?";
	}
	else // File is a text delimited file
	{
		m_bExcel = false;
		m_sSeparator = SheetOrSeparator;
	}

	if (m_bExcel) // If file is an Excel spreadsheet
	{
		m_Database = new CDatabase;
		GetExcelDriver();                // 运行到此处,进入GetExcelDriver(),寻找驱动
		m_sDsn.Format(_T("DRIVER={%s};DSN='';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB=\"%s\";DBQ=%s"), m_sExcelDriver, m_sFile, m_sFile);

		if (Open())
		{
			if (m_bBackup)
			{
				if ((m_bBackup) && (m_bAppend))
				{
					CString tempSheetName = m_sSheetName;
					m_sSheetName = "CSpreadSheetBackup";
					m_bAppend = false;
					if (!Commit())
					{
						m_bBackup = false;
					}
					m_bAppend = true;
					m_sSheetName = tempSheetName;
					m_dCurrentRow = 1;
				}
			}
		}
	}
	else // if file is a text delimited file
	{
		if (Open())
		{
			if ((m_bBackup) && (m_bAppend))
			{
				m_stempString = m_sFile;
				m_stempSql.Format(_T("%s.bak"), m_sFile);
				m_sFile = m_stempSql;
				if (!Commit())
				{
					m_bBackup = false;
				}
				m_sFile = m_stempString;
			}
		}
	}
}

GetExcelDriver();     // 运行到此处,进入GetExcelDriver(),寻找驱动。

函数如下:其中char 改为 wchar_t , strstr 改为 _tcsstr, strchr 改为 wcschr

void CSpreadSheet::GetExcelDriver()
{
	//char szBuf[2001];
	//char *pszBuf = szBuf;        // 修改如下,把char 改为 wchar_t
	wchar_t szBuf[2001];
	wchar_t *pszBuf = szBuf;
	wchar_t excl[] = L"Excel";

	WORD cbBufMax = 2000;
	WORD cbBufOut;

	

	// Get the names of the installed drivers ("odbcinst.h" has to be included )
	if(!SQLGetInstalledDrivers(szBuf,cbBufMax,&cbBufOut))
	{
		m_sExcelDriver = "";
		return;			// 添加
	}
	
	// Search for the driver...
	do
	{
		//if(strstr(pszBuf, "Excel") != 0)        // strstr改为 _tcsstr
		if(_tcsstr(pszBuf, excl) != 0)
		{
			// Found !
			m_sExcelDriver = CString(pszBuf);
			break;
		}
		//pszBuf = strchr(pszBuf, '\0') + 1;
		pszBuf = wcschr(pszBuf, '\0') + 1;           // strchr 改为wcschr
	}
	while(pszBuf[1] != '\0');
	return;
}

当运行到 if(!SQLGetInstalledDrivers(szBuf,cbBufMax,&cbBufOut)) 语句时, 跳转到strsafe.h文件中

STRSAFEAPI
StringCchPrintfA(
    __out_ecount(cchDest) STRSAFE_LPSTR pszDest,
    __in size_t cchDest,
    __in __format_string STRSAFE_LPCSTR pszFormat,
    ...)
{
    HRESULT hr;

    hr = StringValidateDestA(pszDest, cchDest, STRSAFE_MAX_CCH);
    
    if (SUCCEEDED(hr))
    {
        va_list argList;

        va_start(argList, pszFormat);

        hr = StringVPrintfWorkerA(pszDest,
                                  cchDest,
                                  NULL,
                                  pszFormat,
                                  argList);            // 卡到此处

        va_end(argList);
    }

    return hr;
}

卡住以后,显示中断,readExcel.exe 中的 0x02e4b1e9 处有未经处理的异常: 0xC0000005: Access violation

显然是内存泄漏造成的。

但是,还没找到原因。

 

参考链接:

https://blog.csdn.net/android_lover2014/article/details/52755936

https://blog.csdn.net/u013472838/article/details/51338263

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值