C#:将简单结构的列表转换为byte []

时间:2010-11-05 15:27:26

标签: c# list struct byte marshalling

在C#4.0中,说我有

List<HSZPAIR> myList

包含三个元素,其中HSZPAIR结构由以下内容定义:

[StructLayout(LayoutKind.Sequential)]
public struct HSZPAIR
{
    public IntPtr hszSvc;
    public IntPtr hszTopic;
}

如何为整个myList创建一个字节数组?在C ++中,您可以将结构数组转换为字节数组。我不知道如何在C#中做到这一点。

我在DDEML库中使用旧的Windows API函数,该函数需要字节数组和数组中的元素数作为参数。如果您对更多背景感兴趣,API函数是:

[DllImport("user32.dll", EntryPoint="DdeCreateDataHandle", CharSet=CharSet.Ansi)]
    public static extern IntPtr DdeCreateDataHandle(int idInst, byte[] pSrc, int cb, int cbOff, IntPtr hszItem, int wFmt, int afCmd);

Here is it's documentation on MSDN。 pSrc参数是HSZPAIR结构的字节数组。数组的大小是cb参数。

3 个答案:

答案 0 :(得分:1)

我认为你需要在extern声明中将pSrc的类型定义为IntPtr,而不是byte []。

答案 1 :(得分:1)

将结构转换为字节数组有点痛苦。你必须自己序列化。但它可能没有必要。

鉴于你的清单:

List<HSZPAIR> myList;

您可以致电ToArray来获取数组:

HSZPAIR[] myArray = myList.ToArray();

现在,更改您的托管原型,使其需要HSZPAIR[]而不是byte[]

public static extern IntPtr DdeCreateDataHandle(
    int idInst, HSZPAIR[] pSrc, int cb, int cbOff, IntPtr hszItem, int wFmt, int afCmd);

那应该有用。毕竟,正如您所指出的,HSZPAIR的数组实际上只是一个字节数组。

答案 2 :(得分:1)

我认为你可以使用Marshal.StructureToPtr。

static byte[] StructureToByteArray(object obj)
{
   int length = Marshal.SizeOf(obj);
   byte[] data = new byte[length];
   IntPtr ptr = Marshal.AllocHGlobal(length);
   Marshal.StructureToPtr(obj, ptr, true);
   Marshal.Copy(ptr, data, 0, length);
   Marshal.FreeHGlobal(ptr);
   return data;
}

至于列表本身,它必须单独序列化。