gpt4 book ai didi

c# - 需要 Pinvoke 结构编码帮助 - System.AccessViolationException

转载 作者:太空狗 更新时间:2023-10-29 23:26:20 24 4
gpt4 key购买 nike

嘿!我刚开始摆弄 pinvoke,遇到了一个问题。我收到 AccessViolationException。首先,是否有某种方法可以调试或追踪导致此错误的字段?唯一写入的是结果结构。

C++ 调用如下所示:

MyFunc(int var1, _tuchar *var2, _tuchar *var3, _tuchar *var4, MyStruct *Result,
_tuchar *var5, _tuchar *var6);

C++ 结构:

typedef struct MyStruct 
{
_tuchar *id;
_tuchar *ErrorMessages;
int int1;
_tuchar language[3];
_tuchar *result;
int type;
int number;
int *type2;
_tuchar **blocks;
}

C# 结构:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MyStruct
{
[MarshalAs(UnmanagedType.LPStr)]
public string Id;

[MarshalAs(UnmanagedType.ByValArray, SizeConst=500)]
public char[] ErrorMessages;

public int int1;

[MarshalAs(UnmanagedType.LPStr)]
public string language;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)]
public char[] result;

public int type;

public int number;

public int type2;

[MarshalAs(UnmanagedType.ByValArray)]
public string[] blocks;

C#方法声明:

[DllImport(MyPath, EntryPoint = "MyEntryPoint", SetLastError = true,
CharSet = CharSet.Unicode)]
internal static extern int MyFunc(int var1, string var2, string var3,
string var4, ref MyStruct Result, string var5, string var6);

C# 调用:

var result = new MyStruct();
MyFunc(0, "var2", "var3", "var4", ref result, "var5", "var6");

希望我没有遗漏任何东西。感谢您的帮助!

最佳答案

哦,伙计!您为第一次摆弄体验选择了一个相当复杂的案例。我建议先做一些简单的事情,然后再转向真正的事情。

首先CharSet=CharSet.Ansi 看起来很可疑。您所有的字符串和字符都是 _tuchar,我收集到 u 的意思是“Unicode”,不是吗?如果是这种情况,您需要 CharSet=CharSet.Unicode

其次,(这是最有可能的罪魁祸首)为什么 ErrorMessages 字段被编码为 ByValArray?您知道这里的 ByVal 意思是“按值”,不是吗?如,不是引用。你知道 C++ 中的小星号表示“引用”,不是吗?那么,为什么您的引用字段 ErrorMessages 被编码为按值数组?如果您不知道,当数组的所有内容都被传递时,数组通常被称为“按值”传递,而不是仅仅将引用(指针)传递到存储所有内容的内存位置。在 C++ 结构定义中,您指定 _tuchar*,这意味着“对包含一个或多个 _tuchars 的内存的引用(指针)”,而在 C# 中您指定 [MarshalAs(UnmanagedType.ByValArray ,SizeConst=500)],意思是“这里应该有500个_tuchars,不多也不少”。看到一个引用(指针)通常需要 4 个字节(或 64 位机器上的 8 个字节),而 500 个 unicode 字符需要 1000 个字节,你在这里有一个明显的不匹配。

第三第四resultblocks 字段也是如此。

第五language字段正好是相反的情况:C++代码说“这里有3个_tuchars”,而C#代码说“有一个引用(指针) ) 到此处的字符串”(如果您不知道,LPStr 表示“指向字符串的长指针”)

最后,在您解决了所有这些问题之后,我建议您执行您的程序并打印出对 Marshal.SizeOf( typeof( MyStruct ) ) 的调用结果。在 .NET 看来,这将确切地告诉您您的结构有多大。转到 C++ 端并打印出 sizeof( MyStruct )。这将为您提供 C++ 对大小的看法。

如果结果不一样,看看哪里出了问题。尝试一个一个地删除字段,直到它们变得相同。这将为您提供罪魁祸首字段。与他们一起工作。

总的来说,我建议您首先需要更好地了解事物的运作方式。这个案例对于初学者来说太复杂了。

祝你好运!

关于c# - 需要 Pinvoke 结构编码帮助 - System.AccessViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5813829/

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