C #: конвертировать список простых структур в байты [] - PullRequest
4 голосов
/ 05 ноября 2010

В C # 4.0, скажем, у меня есть

List<HSZPAIR> myList

с тремя элементами , где структура HSZPAIR определяется как:

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

Как создать байтовый массив для всего myList? В C ++ вы можете просто преобразовать массив структур в байтовый массив. Я не уверен, как это сделать в C #.

Я использую старую функцию Windows API в библиотеке DDEML, для которой в качестве аргументов требуется массив байтов и количество элементов в массиве. Если вас интересует дополнительная информация, функция 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);

Вот документация по MSDN . Аргумент pSrc - это байтовый массив структур HSZPAIR. Размер массива - это аргумент cb.

Ответы [ 3 ]

1 голос
/ 05 ноября 2010

Преобразование структуры в массив байтов довольно болезненно. Вы должны сериализовать это самостоятельно. Но это может и не понадобиться.

Учитывая ваш список:

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 на самом деле является просто массивом байтов.

1 голос
/ 05 ноября 2010

Я думаю, вы можете использовать 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;
}

Что касается самого списка, то его нужно будет сериализовать отдельно.

1 голос
/ 05 ноября 2010

Я считаю, что вам нужно определить тип pSrc в объявлении extern как IntPtr, а не byte [].

...