将函数从Visual Basic 6.0转换为C#会引发AccessViolationException

将函数从Visual Basic 6.0转换为C#会引发AccessViolationException,c#,vb6,access-violation,C#,Vb6,Access Violation,我正在将函数转换为: 在C#中,我将函数声明为: [DllImport("archivedll")] public static extern int RequestOperation(int dth ,StringBuilder searchRequestBuf, int bufferLen, int fieldNum, int op, string value); 从C#调用RequestOperation时,会引发异常: [System.AccessViolationException]

我正在将函数转换为:

在C#中,我将函数声明为:

[DllImport("archivedll")]
public static extern int RequestOperation(int dth ,StringBuilder searchRequestBuf, int bufferLen, int fieldNum, int op, string value);
从C#调用RequestOperation时,会引发异常:

[System.AccessViolationException]= {”试图读取或写入受保护的数据 记忆。这通常是一个迹象 另一个内存已损坏。“}


我成功地调用了许多其他类似的函数,但只有此函数引发异常。

此函数显然没有引发
AccessViolationException
-相反,它通过“尝试读取或写入受保护内存”生成访问冲突错误。NET正在将该错误转换为
AccessViolationException


您必须弄清楚为什么它“试图读取或写入受保护的内存”。特别是,您是否初始化了要传递给它的
StringBuilder
?请发布用于调用此方法的代码。

我认为函数声明中的
StringBuilder
与此有关。您应该只使用普通的
字符串

///返回类型:int
/// Return Type: int
///dth: int
///searchRequestBuf: BSTR->OLECHAR*
///buflen: int
///FieldNum: int
///OP: int
///value: BSTR->OLECHAR*
[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="RequestOperation")]
///dth:int ///searchRequestBuf:BSTR->OLECHAR* ///buflen:int ///FieldNum:int ///OP:int ///值:BSTR->OLECHAR* [System.Runtime.InteropServices.DllImportAttribute(“,EntryPoint=“RequestOperation”)]

公共静态extern int RequestOperation(int dth、[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.BStr)]字符串searchRequestBuf、int buflen、int FieldNum、int OP、[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.BStr)]字符串值

是的,我已使用Capicity=4096 Vb6代码初始化StringBuilder,调用Dim bufSearchRequest作为String*4096 retCode=SearchRequestOperation(hDocumentType,bufSearchRequest,Len(bufSearchRequest),fieldIdx,queryType,stringQuery),这是C#调用StringBuilder searchRequest=new StringBuilder(4096);retCode=RequestOperation(hDocumentType,searchRequest,searchRequest.Capacity,index,queryType,query);正如Eran所说,错误显然是发生的,因为您正在将StringBuilder对象传递到一个需要字符串的函数中。它们不能互换。Eran不正确。DLL通过searchRequestBuf参数返回字符串。因此,必须使用StringBuilder。仅当DLL不修改输入字符串时,才能使用字符串。看看这里的例子@ThaiV你能解释一下你为什么接受这个答案吗?初始化StringBuffer是否解决了问题?@ThaiV:这个答案对您有帮助吗?StringBuilder参数类型用于[OutAttribute],我认为这没关系。然而,您没有理由使用StringBuilder作为参数,因为它假设以优化的性能构建字符串,而不是作为数据容器传递。-1 Eran,您是错误的。DLL通过searchRequestBuf参数返回字符串。因此必须使用StringBuilder-不能使用字符串,因为.NET字符串是不可变的。看看MSDN上的例子哇,这真的很奇怪。。。我想你只能指望微软提供这种粗糙的实现。我的意思是-它是一个字符串生成器,它构建字符串。。。它与通过ref传递数据有什么关系?!NET的P/Invoke机制在托管代码和非托管代码之间封送数据。它将[输出]字符串数据封送到
StringBuilder
中。在调用P/Invoke之前,您应该先阅读它的“原油”。在VB6
Declare
语句中,ByVal字符串被编组为指向ANSI字符串的指针,而不是BSTR。如果您希望以这种方式编写,则两次都应该是
System.Runtime.InteropServices.UnmanagedType.LPStr
/// Return Type: int
///dth: int
///searchRequestBuf: BSTR->OLECHAR*
///buflen: int
///FieldNum: int
///OP: int
///value: BSTR->OLECHAR*
[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="RequestOperation")]