我正在运行一个基于MFC对话框的应用程序。我有一个在参考类(代码片段之外)中运行的串行通信线程,它将 String^ 发送到对话框(因此我可以将通信放在窗口中)。问题是(正如您从注释代码中看到的那样),每次我尝试对该字符串执行任何操作(除了将其分配给局部变量)时,我都会得到"DLP_Printer_Control.exe发生了'System.AccessViolationException'类型的未处理异常
其它信息:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。
在此代码段中,崩溃的是 atoi。我正在使用atoi,因为我的想法是尝试将每个字符串元素复制到ASCII,然后按值复制到成员CString。那行不通。每个注释行都会产生一个异常。我起诉它与尝试访问源自托管内存的内容有关。有什么解决方法建议吗?
bool CDLP_Printer_ControlDlg::UpdateCommsWindow_right(String^ strCommsLine)
{
CString strTemp = strCommsLine;
LPWSTR charTemp;
int i = 0;
int i_len = strTemp.GetLength();
if (i_len == 0)
return false;
charTemp= strTemp.GetBuffer(i_len);
i =atoi((const char*)charTemp[0]);
strTemp.ReleaseBuffer();
//if (m_strCommsLeft.IsEmpty())
// return false;
//LPCTSTR szTemp = (LPCTSTR)strTemp;
//m_rightCommsLabel.SetWindowTextW((LPCTSTR)strTemp);
//m_rightCommsLabel.SetWindowTextW(szTemp);
//m_rightCommsLabel.SetWindowTextW(L"SUCCESS");
return true;
}
在此代码段中,崩溃的是 atoi。
i =atoi((const char*)charTemp[0]);
简短的回答是,charTemp[0]
是一个TCHAR
而不是指针,因此虽然 const char *
强制转换允许它编译,但传递给 atoi
的值不是指向有效内存的指针,这会导致System.AccessViolationException
异常。快速解决方法是将该行替换为 i = _wtoi(charTemp);
,甚至i = _ttoi(strTemp);
如下所述。
LPWSTR charTemp; /*...*/ charTemp= strTemp.GetBuffer(i_len);
仅当项目是为 Unicode 构建时,才会编译。这是当今Windows中的常见情况,但值得注意的是,因为您稍后会混合使用非Unicode函数,例如atoi
。对于可以正确编译宽字符集和窄字符集的变体,您可以将声明替换为与字符集无关的LPTSTR charTemp;
。
i =atoi((const char*)charTemp[0]);
仅当项目不是为 Unicode 构建时,这才会编译,因为atoi
需要一个普通的旧const char *
作为参数。字符集中性 MS 映射是_ttoi的,因此在删除错误的[0]
和const char *
转换后,代码将变得简单i = _ttoi(charTemp);
。
最后,CString
具有内置的LPCTSTR
运算符,因此无需GetBuffer/ReleaseBuffer
和使用中间LPTSTR charTemp;
。以下内容将在一个步骤中完成相同的工作。
i = _ttoi(strTemp);