C++。NET包装器:尝试读取或写入受保护的内存。这通常表示其他内存已损坏 我有一个用于非托管MFC DLL的C++ .NET包装器。此包装器由vb.net dll使用,调用到我的c#代码中。在运行时,有时包装器会引发尝试读取或写入受保护内存的异常 System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt

C++。NET包装器:尝试读取或写入受保护的内存。这通常表示其他内存已损坏 我有一个用于非托管MFC DLL的C++ .NET包装器。此包装器由vb.net dll使用,调用到我的c#代码中。在运行时,有时包装器会引发尝试读取或写入受保护内存的异常 System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt,c#,c++,memory,mfc,wrapper,C#,C++,Memory,Mfc,Wrapper,它似乎随机出现在我的“While”循环中。有时它在开始时,有时在中间,有时没有被抛出。 工作原理: 我的程序需要一个MFCDLL。我的程序中引用了一个wrapper.dll(c++)和一个myVbDll.dll(vb.net)。我还添加了MFC dll作为内容,因为它不是有效的COM组件。这就是它的工作原理: myprogram.exe->myVbDll.dll->wrapper.dll->myMFC.dll->myMFC函数 信息:如果我设置field=“无论如何”在调用MyWrappedFu

它似乎随机出现在我的“While”循环中。有时它在开始时,有时在中间,有时没有被抛出。

工作原理: 我的程序需要一个MFCDLL。我的程序中引用了一个wrapper.dll(c++)和一个myVbDll.dll(vb.net)。我还添加了MFC dll作为内容,因为它不是有效的COM组件。这就是它的工作原理:

myprogram.exe->myVbDll.dll->wrapper.dll->myMFC.dll->myMFC函数

信息:如果我设置
field=“无论如何”在调用MyWrappedFunction之前,不会抛出错误

更新:经过多次更改后,问题仍然存在。这次我看一下如何将unicode字符串转换为Ansi。可能有什么东西要找。。。因为当您像上面那样在字符串中写入文本时,它可以工作,但是当使用ToString函数时,它就不工作了

有人能说出为什么会发生这种情况吗

我的c#程序的一部分(使用TextFieldParser从.csv文件中读取5000行以获取字段):

VB.net Dll的一部分,由我的c#程序调用:

Public Class myVbDll

Public Declare Auto Function MyWrappedFunction Lib "myWrapper.dll" (ByVal name As String, ByVal opt As Boolean) As String

End Class
Public Class myVbDll
    <DllImport("Wrapper.dll", CharSet:=CharSet.Unicode)> Public Shared Function MyWrappedFunction (ByVal nom As String, ByVal opt As Boolean) As String
    End Function
End Class
MFC包装的一部分,由VB.net Dll调用(错误肯定不会进入MFC Dll):

这是C++代码中的<>强>非常/强>严重错误。您正在返回局部变量的地址。由A2OLE()创建的缓冲区。它调用C++代码中的未定义行为。当您从C++代码调用这个函数时,这会有意外地发生,您可能有其他的函数调用,它覆盖了过去使用的局部变量的堆栈地址。当pinvoke函数调用时,这些几率变为零,堆栈地址将被pinvoke marshaller函数调用删除。如果这本身不会导致崩溃,那么pinvoke marshaller将确保在尝试使用CoTaskMemFree()释放字符串时崩溃

<>你必须首先修复C++代码。不,只是将指针复制到C_resultat中并不是一个解决方案

请注意,尝试拯救此函数没有多大意义。它不会做任何你在C中做不到的事情。只需为“MyFunction”函数编写一个[DllImport]属性

这是C++代码中的<>强>非常/强>严重错误。您正在返回局部变量的地址。由A2OLE()创建的缓冲区。它调用C++代码中的未定义行为。当您从C++代码调用这个函数时,这会有意外地发生,您可能有其他的函数调用,它覆盖了过去使用的局部变量的堆栈地址。当pinvoke函数调用时,这些几率变为零,堆栈地址将被pinvoke marshaller函数调用删除。如果这本身不会导致崩溃,那么pinvoke marshaller将确保在尝试使用CoTaskMemFree()释放字符串时崩溃

<>你必须首先修复C++代码。不,只是将指针复制到C_resultat中并不是一个解决方案


请注意,尝试拯救此函数没有多大意义。它不会做任何你在C中做不到的事情。只需为“MyFunction”函数编写一个[DllImport]属性。

最后,我解决了这个问题

问题的真正原因是编码字符串。下面是我为改进代码所做的所有更改

如果你看到我做的可疑的事情可以改进,请随意评论

我的主要申请:

private void processImport()
{
    string[] fields;
    string field ;
    string temp = "";
    byte[] tempByte;

    TextFieldParser parser = new TextFieldParser(textbox_csv.Text, System.Text.Encoding.UTF8);
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(";");

    while (!parser.EndOfData)
    {
        fields = parser.ReadFields();
        field = fields[0];
        temp = RemoveDiacritics(field).ToUpper();
        //this line is very important. It seems to change the Encoding of my string to Unicode.
        temp = temp.Normalize(NormalizationForm.FormC);
        field = myVbDll.MyWrappedFunction(temp, false);
    }
    parser.Close();
}

//Transforms the culture of a letter to its equivalent representation in the 0-127 ascii table, such as the letter 'é' is substituted by an 'e'
public string RemoveDiacritics(string s)
{
    string normalizedString = null;
    StringBuilder stringBuilder = new StringBuilder();
    normalizedString = s.Normalize(NormalizationForm.FormD);
    int i = 0;
    char c = '\0';

    for (i = 0; i <= normalizedString.Length - 1; i++)
    {
        c = normalizedString[i];
        if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
        {
            stringBuilder.Append(c);
        }
    }

    return stringBuilder.ToString().ToLower();
}

最后,我解决了这个问题

问题的真正原因是编码字符串。下面是我为改进代码所做的所有更改

如果你看到我做的可疑的事情可以改进,请随意评论

我的主要申请:

private void processImport()
{
    string[] fields;
    string field ;
    string temp = "";
    byte[] tempByte;

    TextFieldParser parser = new TextFieldParser(textbox_csv.Text, System.Text.Encoding.UTF8);
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(";");

    while (!parser.EndOfData)
    {
        fields = parser.ReadFields();
        field = fields[0];
        temp = RemoveDiacritics(field).ToUpper();
        //this line is very important. It seems to change the Encoding of my string to Unicode.
        temp = temp.Normalize(NormalizationForm.FormC);
        field = myVbDll.MyWrappedFunction(temp, false);
    }
    parser.Close();
}

//Transforms the culture of a letter to its equivalent representation in the 0-127 ascii table, such as the letter 'é' is substituted by an 'e'
public string RemoveDiacritics(string s)
{
    string normalizedString = null;
    StringBuilder stringBuilder = new StringBuilder();
    normalizedString = s.Normalize(NormalizationForm.FormD);
    int i = 0;
    char c = '\0';

    for (i = 0; i <= normalizedString.Length - 1; i++)
    {
        c = normalizedString[i];
        if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
        {
            stringBuilder.Append(c);
        }
    }

    return stringBuilder.ToString().ToLower();
}

我想你已经回答了你自己的问题。“如果我设置field=”无论如何“;永远不会抛出错误!!”但我需要将字段放入.csv文件中!我不知道那是什么意思。常识应该规定给变量一些初始值,即使该值是空字符串或null。以后您可以在该变量中添加其他值。如果我将此行“field=fields[0];”替换为“field=”ANYTHING“;”。错误不会发生。但如果我不这么做,错误就来了occurs@Robert哈维。“您可以在以后将其他值放入该变量。”如果我尝试从文件中放入该值,在大多数情况下,AccessViolationException会在不同字段上随机发生。我想您已经回答了自己的问题。“如果我设置field=”无论如何“;永远不会抛出错误!!”但我需要将字段放入.csv文件中!我不知道那是什么意思。常识应该规定给变量一些初始值,即使该值是空字符串或null。以后您可以在该变量中添加其他值。如果我将此行“field=fields[0];”替换为“field=”ANYTHING“;”。错误不会发生。但如果我不这么做,错误就来了occurs@Robert哈维。“以后您可以在该变量中添加其他值。”如果我尝试从文件中添加该值,在大多数情况下,AccessViolationException会随机出现在不同的字段中。您知道如何操作吗?由于我在Cstring和C++之间的转换过程中丢失了所有的数据,解释如何编写正确的C++代码需要一本书,它不适合这样的答案。我试图在回答的最后一段提到这一点。请尝试利用我所记录的内容,如果这个C++函数没有用于任何其他事情,除了p援引,那么使用COTASKMeMalAcLoad(),这样pPoNKE封送器就很高兴了。但是我必须继续使用A2OLE或A2W吗?这是我发现的唯一一种将CString投射到LPWSTR的方法。我也不知道
private void processImport()
{
    string[] fields;
    string field ;
    string temp = "";
    byte[] tempByte;

    TextFieldParser parser = new TextFieldParser(textbox_csv.Text, System.Text.Encoding.UTF8);
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(";");

    while (!parser.EndOfData)
    {
        fields = parser.ReadFields();
        field = fields[0];
        temp = RemoveDiacritics(field).ToUpper();
        //this line is very important. It seems to change the Encoding of my string to Unicode.
        temp = temp.Normalize(NormalizationForm.FormC);
        field = myVbDll.MyWrappedFunction(temp, false);
    }
    parser.Close();
}

//Transforms the culture of a letter to its equivalent representation in the 0-127 ascii table, such as the letter 'é' is substituted by an 'e'
public string RemoveDiacritics(string s)
{
    string normalizedString = null;
    StringBuilder stringBuilder = new StringBuilder();
    normalizedString = s.Normalize(NormalizationForm.FormD);
    int i = 0;
    char c = '\0';

    for (i = 0; i <= normalizedString.Length - 1; i++)
    {
        c = normalizedString[i];
        if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
        {
            stringBuilder.Append(c);
        }
    }

    return stringBuilder.ToString().ToLower();
}
Public Class myVbDll
    <DllImport("Wrapper.dll", CharSet:=CharSet.Unicode)> Public Shared Function MyWrappedFunction (ByVal nom As String, ByVal opt As Boolean) As String
    End Function
End Class
typedef void (*MYFUNCTION)(CString&, CString&, BYTE);
MYFUNCTION Myfunction;

LPWSTR _stdcall MyWrappedFunction(LPWSTR ValInput, BYTE opt)
{
    HINSTANCE gLibtestDLL=NULL;
    CString S_ValInput(ValInput);
    CString S_resultat;

    gLibtestDLL = AfxLoadLibrary(TEXT(".\\test.dll"));
    if(gLibtestDLL == NULL)
    {
        MessageBox(NULL, TEXT("unable to load test.DLL"), TEXT("Error"),MB_OK | MB_ICONINFORMATION);
        return NULL;
    }

    Myfunction = (MYFUNCTION)GetProcAddress(gLibtestDLL, "Myfunction");
    if (Myfunction == NULL)
    {
        MessageBox(NULL, TEXT("Can't find Myfunction."), TEXT("Error"),MB_OK | MB_ICONINFORMATION);

        return NULL;
    }
    //******************************************************************

    S_resultat.Format("%64c", ' ');
    Myfunction(S_ValInput , S_resultat , opt);  //Run MFC function
    S_resultat.TrimRight();
    S_resultat.ReleaseBuffer();

    char* tmp = (char*) CoTaskMemAlloc((S_resultat.GetLength()*2)+1);
    memset(tmp,0,sizeof(tmp));
    strcpy_s(tmp, (S_resultat.GetLength()+1), S_resultat.GetBuffer(S_resultat.GetLength()));
    S_resultat.ReleaseBuffer();

    wchar_t wtext[1024];
    memset(wtext,0,sizeof(wtext));
    mbstowcs(wtext, tmp, strlen(tmp)+1);//Plus \0
    LPWSTR resultat = wtext;

    AfxFreeLibrary(gLibtestDLL);

    return resultat;
}