ICustomMarshaler可变长度数组

时间:2011-10-21 21:15:55

标签: c# marshalling

我知道可以在数组中使用索引来指定编组C数组的数组长度。但是,我想做的有点不同。

我希望这个大小是一个带前缀的Int16。如果我把它作为数组的一个条目,我无法控制计数说明符的封送大小。

因此,简而言之,我如何编写一个自定义编组器,将Int16作为计数前缀。

请注意,我必须序列化数据,因此不允许使用IntPtrs。

我难以理解的部分是如何实现GetNativeDataSize。那时我没有IntPtr或Managed Object,所以我如何能够编组Int16以获得计数。

例如。

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
class Something
{
    [MarshalAs(UnmanagedType.CustomMarshaler ... ]
    public ArrayItem[];
}

另一个班级

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
class ArrayItem
{
    public int Item;
}

在Native端,这将显示为

struct
{
    short count;
    int[] Item;
}

但是由于托管端的每个可变长度数组都会这样做,我想要一个自定义编组器为我附加计数。

问题是

  • 我不知道GetNativeDataSize应该做什么,或者它将如何工作,因为我没有任何对本机数据的引用。
  • 我不能依赖LPArray,因为计数必须是Int16
  • 数组项目是否正确编组,或者数组自定义编组器是否隐藏了项目编组器,或者我是否必须实现一些通用编组器(如果可能的话)。

1 个答案:

答案 0 :(得分:0)

我要说的是......一个定制的封送者感觉有点矫枉过正。如果您真的想使用自定义封送程序执行此操作,则必须使用unsafe块/方法和指针数学来编写数据。

为什么没有类似于你的原生结构的类,并在编组时将数组包装在其中?真的,你正试图通过一个结构;自定义封送程序的唯一原因是从数组中神奇地生成该结构。最好避免魔法,IMO,同时让默认的封送者做咕噜咕噜的工作。