我有一个未管理的 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
它似乎在我的“While”循环中随机发生。有时它在开始时抛出,有时在中间抛出,有时什么也不抛出。
工作原理:我的程序需要一个 MFC dll。我的程序中有一个 wrapper.dll(c++) 和一个 myVbDll.dll(vb.net) 。我还添加了 MFC dll 作为内容,因为它不是有效的 COM 组件。这就是它的工作原理:
myProgramm.exe->myVbDll.dll->wrapper.dll->myMFC.dll->myMFCfunction
信息:如果我field = "WHATSOEVER";
之前设置调用 MyWrappedFunction,则永远不会抛出错误!
更新:经过多次更改,问题仍然存在。我看看这次将 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;
}