c# - 编码问题

标签 c# interop pinvoke marshalling

我有一个与读卡器交互的 C++ DLL。它需要一个指向数据结构的指针,这不是问题。但是,当尝试与 C# 中的 DLL 交互时,我遇到了各种各样的问题。写入 protected 内存时出错,应用程序在执行 getData 命令后刚刚关闭,等等。这就是我们所拥有的。

头文件中的 C++ 方法

void readCard(cardData* dataBuffer);

C#代码

Wrapper.cs
public struct cardData{
   Byte[] data01;
   Byte[] data02;
}

[dllImport("card.dll")]
public static extern void readCard(ref cardData data);

form1.cs

Wrapper.cardData tmpData = new wrapper.cardData();
tmpData.data01 = new Byte[];
tmpData.data02 = new Byte[];
readCard(ref tmpData);

我一直在尝试使用帮助文件和其他帖子来解决这个问题,因为似乎很多人在尝试使用 C/C++ DLL 时遇到了麻烦。我什至尝试用 C++ 编写整个程序并让它返回一个字符串,其中包含在 C++ DLL 中解析的数据,但这会引发读取/写入 protected 内存错误

最佳答案

我在您的代码中看到的最大问题是您没有为 byte[] 成员提供明确的大小。如果没有这个大小运算符,编码器会将它们视为简单的引用类型。生成的结构在 32 位平台上的大小为 8 字节,几乎肯定会导致写入 protected 内存。

假设字节数组在 C 代码中具有固定大小,您应该使用 MarshalAs 属性为字节数组提供托管代码中相同的语义。这确实需要给它们一个固定的尺寸。

[StructLayout(LayoutKind.Sequential)]
public struct cardData{
   [MarshalAs(UnmanagedType.ByValArray, SizeConst=300)]
   Byte[] data01;
   [MarshalAs(UnmanagedType.ByValArray, SizeConst=300)]
   Byte[] data02;
}

将 300 更改为数组 native 代码中指定的任何大小。

此外,您还应该添加 StructLayout 属性。

关于c# - 编码问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1189251/

相关文章:

c# - LINQ - 仅列出最低价格

c# - 调试 .NET Framework 的源代码仅显示在 Visual Studio 2010 中的反汇编

c# - 自动实现的属性必须同时定义 get 和 set 访问器

c# - html 敏捷包删除 child

F# 和 COM api 向下转换问题

c# - 此 C 函数的正确 C# PInvoke 签名

c - 使用 OpenCL 传输

c++ - 一些基本的 COM 问题

c# - Silverlight 用户控件的句柄

c# - Pinvoke 中的一个问题