Multithreading MFC/CLI混合模式';System.AccessViolationException';

Multithreading MFC/CLI混合模式';System.AccessViolationException';,multithreading,mfc,dialog,command-line-interface,Multithreading,Mfc,Dialog,Command Line Interface,我正在运行一个基于MFC对话框的应用程序。我有一个串行通信线程在一个引用类中运行(在代码段之外),它向对话框发送一个字符串^。问题是(正如您从注释代码中看到的),每当我尝试对该字符串执行任何操作(除了将其分配给局部变量)时,我都会在DLP_Printer_Control.exe中出现“System.AccessViolationException”类型的未处理异常 其他信息:试图读取或写入受保护的内存。这通常表示其他内存已损坏。” 在这个片段中,是atoi崩溃了。我之所以使用atoi,是因为我的

我正在运行一个基于MFC对话框的应用程序。我有一个串行通信线程在一个引用类中运行(在代码段之外),它向对话框发送一个字符串^。问题是(正如您从注释代码中看到的),每当我尝试对该字符串执行任何操作(除了将其分配给局部变量)时,我都会在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
not指针,因此当
const char*
cast允许它编译时,传递给
atoi
的值是一个指向有效内存的指针,这会导致
系统.AccessViolationException
异常。快速修复方法是将该行替换为
i=\u wtoi(charTemp),甚至是
i=\u ttoi(strTemp)如下所述

LPWSTR charTemp;/*…*/charTemp=strTemp.GetBuffer(i_len)

只有在项目是为Unicode构建的情况下,才会编译此文件。这是当今Windows中的常见情况,但值得注意的是,稍后您将混合使用非Unicode函数,如
atoi
。对于能够正确编译宽字符集和窄字符集的变体,可以用字符集中性
LPTSTR charTemp

i=atoi((const char*)charTemp[0])

由于
atoi
需要一个普通的
const char*
作为参数,因此只有当项目不是为Unicode构建时,才会编译此文件。字符集中性MS映射是,因此在删除错误的
[0]
常量char*
强制转换后,代码将变成简单的
i=\u ttoi(charTemp)

最后,
CString
有一个内置的
LPCTSTR
操作符,因此不需要
GetBuffer/ReleaseBuffer
和使用中间
LPTSTR charTemp。以下内容将在一个步骤中完成相同的工作

i = _ttoi(strTemp);

非常感谢。_ttoi()停止了那个错误,但结果证明这是一个骗局。事实上,如果我有一个成员int,那么将我设置为这个成员int,在我这样做的时候,我会得到“异常抛出:'System.NullReferenceException'”;(
如果我有一个成员int[…]
,如果通过空对象指针调用成员函数,就会发生这种情况。但是如果没有MCVE,就无法猜测。