2016-07-06 85 views
-1

我正在运行基于MFC对话框的应用程序。我有一个serial-comms线程运行在一个引用类(代码片段之外)中,它向对话发送一个String ^(所以我可以把这些通信放在一个窗口中)。问题是(正如您从注释代码中看到的那样)每当我尝试对该字符串执行任何操作时(除了将其分配给本地变量),我都会收到“DLP_Printer_Control.exe中发生类型为”System.AccessViolationException“的未处理异常MFC/CLI混合模式'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; 
} 

回答

1

在这个片段中,它是一个崩溃的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);

如果这个项目是专为统一这只会编译。这是Windows现在的常见情况,但值得注意的是,因为您稍后会混合使用非Unicode功能,例如atoi。对于可以针对宽字符和窄字符正确编译的变体,您可以将该声明替换为字符集中立的LPTSTR charTemp;

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

这如果项目是因为atoi内置的Unicode需要一个普通的老const char *作为参数,只会编译。字符集中立的MS映射是_ttoi,所以在投下错误的[0]const char *后,代码将变为简单i = _ttoi(charTemp);

最后,CString有一个内置的LPCTSTR运营商,所以没有必要GetBuffer/ReleaseBuffer和使用一个中间LPTSTR charTemp;。以下将一步完成相同的工作。

i = _ttoi(strTemp); 
+0

非常感谢。_ttoi()停止了这个错误,但这竟然是一只红鲱鱼。其实,如果我有一个成员int,然后将我设置为此成员int,我得到“异常抛出:'System.NullReferenceException'”我做它的时刻;( –

+0

'如果我有一个成员int [...] '如果你通过一个NULL对象指针调用成员函数,会发生这种情况,但是如果没有MCVE就不可能猜测出来。 – dxiv