Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C#向dll传递固定长度字符串时获取AccessViolationException_C#_Excel_Dllimport_Stringbuilder_Access Violation - Fatal编程技术网

从C#向dll传递固定长度字符串时获取AccessViolationException

从C#向dll传递固定长度字符串时获取AccessViolationException,c#,excel,dllimport,stringbuilder,access-violation,C#,Excel,Dllimport,Stringbuilder,Access Violation,我有以下(VB6?)代码可以在VBA for Excel中完美工作。我正在使用的dll(x.dll)对我来说是一个“黑匣子”。我不知道它是用什么写的,不管是不是非托管的。从历史技术的角度来看,我对它知之甚少。我只知道这个函数在从Excel VBA调用时可以工作,而在从C#调用它时,我无法同样地让它工作,我认为我应该能够。同样,dll使用并更改了c.b128的值 'In VBA for excel the value inside "c.b128" is changed from '" 12345

我有以下(VB6?)代码可以在VBA for Excel中完美工作。我正在使用的dll(x.dll)对我来说是一个“黑匣子”。我不知道它是用什么写的,不管是不是非托管的。从历史技术的角度来看,我对它知之甚少。我只知道这个函数在从Excel VBA调用时可以工作,而在从C#调用它时,我无法同样地让它工作,我认为我应该能够。同样,dll使用并更改了c.b128的值

'In VBA for excel the value inside "c.b128" is changed from
'" 1234567890123456789012345678901234567890123456789012345678901234567890123456789                                                 "
'to
'" 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 123456789                                          "

Excel代码的VBA
我试图在.NET中实现同样的功能,但在返回“returndllspace(-1,-1,c,d);”时出错 尝试读取或写入受保护内存的[…]中发生system.accessviolationexception类型的未处理异常。其他内存已损坏

我需要将其转换为.NET,然后得到一个AccessViolationException。我到处都读到StringBuilders保留的内存可以被C#中的DLL访问。我试过“ref StringBuilder”,我试过使用byte[],我试过使用不安全的描述符,我不明白。另外,如果有一种方法可以让我使用IDE查看内存中发生的更多事情,这也会对我有所帮助。我可以在本地和监视窗口中看到我的所有变量,但我看不到,也不知道如何查看有关抛出异常的更多详细信息。我正在Win32位操作系统机器上使用Visual Studio Express 2013 for Windows桌面

这是我的c代码的一个片段


C#代码片段

VBA代码清楚地表明,您拥有的实际上是一个包含固定长度字符串的结构。这意味着
StringBuilder
是错误的类型。您应改为使用:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct k128
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string b128;
}
另外,据我所知,VBA默认使用
ByRef
。因此,C#宣言应该是:

[DllImport(@"x.dll")]
private static extern int dllSpace(
    ref int aInfo,
    ref int bVec,
    ref k128 cQry,
    ref k128 dErr
);
现在,
ref k128
与容量为128的
StringBuilder
编组时具有相同的内存布局,因此您可以更方便地切换回:

[DllImport(@"x.dll")]
private static extern int dllSpace(
    ref int aInfo,
    ref int bVec,
    StringBuilder cQry,
    StringBuilder dErr
);

尝试捕获Win32Exception
catch(Win32Exception w)
然后可以调用
var e=w.GetBaseException()
获取有关异常的更多详细信息。感谢您对@vendettamit的响应,我遇到了问题。感谢您对@vendettamit的响应,我遇到了问题。
public int StartTheDataSpace(){//我还没有完全准备好这里…//实际上有一个数组,整数通过该数组传递int[]try1={0,-1,-1,2,0,0,0,0};StringBuilder c=new StringBuilder(128);StringBuilder d=new StringBuilder(128);c.Append(“1234567890134[…]”);try{return dllSpace(try1[1],try1[1],c,d);}catch(System.ComponentModel.Win32Exception ex){Console.WriteLine(ex.Data);return-1;}
以上代码对我无效。。。我想我知道如何实现try-catch…在这里我想我尝试了每种组合。谢谢David Heffernan,我很不好意思地说我已经在这个问题上工作了很多天了。我只是在两个整数声明前面添加了ref,dllSpace返回0,这是“无错误”响应。再次感谢。
[DllImport(@"x.dll")]
private static extern int dllSpace(
    ref int aInfo,
    ref int bVec,
    ref k128 cQry,
    ref k128 dErr
);
[DllImport(@"x.dll")]
private static extern int dllSpace(
    ref int aInfo,
    ref int bVec,
    StringBuilder cQry,
    StringBuilder dErr
);