Das*_*shu 5 c# pinvoke marshalling
嘿! 我刚开始摆弄pinvoke并遇到了问题.我收到了AccessViolationException.首先,有没有办法调试或追踪哪个字段导致此错误?唯一要写的是结果结构.
c ++调用如下:
MyFunc(int var1, _tuchar *var2, _tuchar *var3, _tuchar *var4, MyStruct *Result,
_tuchar *var5, _tuchar *var6);
Run Code Online (Sandbox Code Playgroud)
c ++结构:
typedef struct MyStruct
{
_tuchar *id;
_tuchar *ErrorMessages;
int int1;
_tuchar language[3];
_tuchar *result;
int type;
int number;
int *type2;
_tuchar **blocks;
}
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
C#电话:
var result = new MyStruct();
MyFunc(0, "var2", "var3", "var4", ref result, "var5", "var6");
Run Code Online (Sandbox Code Playgroud)
希望我没有遗漏任何东西.谢谢你的帮助!
噢,伙计!您为您的第一次拨弄体验选择了一个相当复杂的案例。我建议先做一些简单的事情,然后再转向真正的事情。
首先,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 个字节,这里有一个明显的不匹配。
第三和第四,同样的一点也适用于result和blocks字段。
第五,该language字段是完全相反的情况:C++代码说“这里有3个_tuchars”,而C#代码说“这里有一个指向字符串的引用(指针)”(如果你不知道,意思是“ LPStrLong”指向 STRing 的指针”)
最后,在解决了所有这些问题之后,我建议您执行您的程序并打印出调用的结果Marshal.SizeOf( typeof( MyStruct ) )。这将告诉您在 .NET 看来您的结构有多大。转到 C++ 端并打印出sizeof( MyStruct ). 这将告诉您 C++ 对大小的看法。
如果结果不同,看看出了什么问题。尝试一一删除字段,直到它们变得相同。这将为您提供罪魁祸首字段。与他们一起工作。
总的来说,我建议您首先需要更好地了解事物的工作原理。这个案例对于初学者来说太复杂了。
祝你好运!
| 归档时间: |
|
| 查看次数: |
2196 次 |
| 最近记录: |