gpt4 book ai didi

c# - C++ .NET Wrapper : Attempted to read or write protected memory. 这通常表示其他内存已损坏

转载 作者:行者123 更新时间:2023-11-28 00:42:42 28 4
gpt4 key购买 nike

我有一个未管理的 MFC dll 的 C++ .net 包装器。这个包装器由 vb.net dll 使用,调用到我的 c# 代码中。在运行时,包装器有时会抛出 Attempted to read or write protected memory 的异常。

System.AccessViolationException: Attempted to read or write protected memory. 
This is often an indication that other memory is corrupt

它似乎是在我的“While”循环中随机出现的。有时它在开头抛出,有时在中间抛出,有时什么都不抛出。

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

myProgramm.exe->myVbDll.dll->wrapper.dll->myMFC.dll->myMFCfunction

信息:如果我在调用 MyWrappedFunction 之前设置 field = "WHATSOEVER";,则永远不会抛出错误!!

更新: 多次修改后,问题依旧。我看这个时候把unicode字符串转成Ansi。可能会找到一些东西...因为当您像上面那样在字符串中写入文本时,它可以工作,但是当使用 ToString 函数时,它就不起作用。

有人能说出为什么会这样吗。

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

string[] fields;
string field ;
string temp = "";

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 = field.ToUpper();
field = myVbDll.MyWrappedFunction(ref temp, false);
}

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

MFC 包装器的一部分,由 VB.net Dll 调用(错误肯定不在 MFC dll 中):

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.LockBuffer();
S_resultat.Format("%64c", ' ');
Myfunction(S_ValInput , S_resultat , opt);
S_resultat.ReleaseBuffer();

S_resultat.LockBuffer();
S_resultat.TrimRight();
S_resultat.ReleaseBuffer();

// CString To UNICODE
USES_CONVERSION;
S_resultat.LockBuffer();
LPWSTR C_tmp= A2OLE(S_resultat.GetBuffer(S_resultat.GetLength()));
S_resultat.ReleaseBuffer();

AfxFreeLibrary(gLibtestDLL);

LPWSTR C_resultat=C_tmp;
//******************************************************************

return C_resultat;

}

最佳答案

LPWSTR C_tmp= A2OLE(S_resultat.GetBuffer(S_resultat.GetLength()));

这是您的 C++ 代码中的一个非常严重的错误。您正在返回局部变量的地址。由 A2OLE() 创建的缓冲区。这会在 C++ 代码中调用未定义的行为。当您从 C++ 代码调用此函数时,这往往会意外起作用,您有可能不会有另一个函数调用覆盖该局部变量曾经所在的堆栈地址。当您 pinvoke 函数时,这些可能性变为零,堆栈地址被 pinvoke marshaller 函数调用删除。如果这本身不会导致崩溃,那么 pinvoke 编码器将确保它在尝试使用 CoTaskMemFree() 释放字符串时崩溃。

您必须先修复您的 C++ 代码。不,只是将指针复制到 C_resultat 中并不能解决问题。

请注意,尝试挽救此功能没有多大意义。它不会做您在 C# 中不能做的任何事情。只需为该“MyFunction”函数编写一个 [DllImport] 属性即可。

关于c# - C++ .NET Wrapper : Attempted to read or write protected memory. 这通常表示其他内存已损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17977263/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com