【问题标题】:Marshalling an unknown Array size编组未知数组大小
【发布时间】:2009-08-06 16:30:34
【问题描述】:

你有一个接受字节数组的结构

byte[]

但是,该数组的大小取决于您提交的图像(宽度x高度)

那么……你是怎么做的

[MarshalAs(UnmanagedType.ByValArray, SizeConst = ???)]
public Byte[] ImageData;

在处理从 C# 传递到 C dll 的字节数组时,sizeconst 是否必须具备?

【问题讨论】:

  • 自定义编组器似乎是唯一的选择。

标签: c# arrays size marshalling


【解决方案1】:

您需要更改编组类型。如果您作为 ByValArray 编组,则需要 SizeConst,但对于其他类型则不需要。详情请看UnmanagedType enum

我怀疑你想编组为指向数组的 C 指针:

[MarshalAs(UnmanagedType.LPArray)]

这将导致它编组到标准 C 数组 (BYTE*),因此只传递一个指针。这样做可以让您传递任何大小的数组。通常,您还希望将数组大小作为另一个参数(或图像宽度/高度/bpp,提供相同的信息)传递,因为 C/C++ 中无法轻松说明这一点。

【讨论】:

  • 感谢里德的回复。但是,我这样做了,现在得到这个错误 Invalid managed/unmanaged type combination (Arrays fields must bepaired with ByValArray or SafeArray) When building the IntPtr and then Marshal.StructureToPtr... 想法?
  • 查看枚举。将需要更多信息。我假设您是从托管 -> 非托管编组,但如果您要反过来,您可以将其编组为 IntPtr(而不是字节 [])或将其设置为使用 SafeArray。跨度>
  • 不幸的是,使用除 [MarshalAs(UnmanagedType.ArrayByVal, sizeConst = xxxx)] 之外的任何东西都会弄乱内存寻址。所以本质上有一个结构(包含一个字节[])需要转换为 IntPtr,以便可以将其传递给 DLL。 byte[] 中的数据被弄乱了。通过将数据从 IntPtr 复制到 byte[] 并查看数据来验证这一点,除非我在结构中设置 MarshalAs,否则一切都已更改。
  • @Olewolfe 双数组也发生在我身上。我正在使用从托管到非托管的 PInvoke。我的双数组也在一个结构内。根据to MSDN,blittable 类型的一维数组,[本身是 blittable]。 但是,包含可变 blittable 类型数组的类型本身不是 blittable。我认为这意味着您的字节数组本身被认为是 blittable,但是一旦您将数组放入结构中,该结构就会失去它的 blittable-ness。
  • 根据this article,解决此问题的方法是使用 SAFEARRAY。
猜你喜欢
  • 2016-03-03
  • 1970-01-01
  • 2014-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-13
  • 2020-11-13
  • 2019-06-30
相关资源
最近更新 更多