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

发布于 2024-09-30 18:40:57 字数 831 浏览 5 评论 0原文

在 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);

这里MSDN 上的文档是 吗? pSrc 参数是 HSZPAIR 结构的字节数组。数组的大小是 cb 参数。

In C# 4.0, say I have

List<HSZPAIR> myList

with three elements where the HSZPAIR struct is defined by:

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

How do I create a byte array for the entire myList? In C++, you could just cast as array of structs down to a byte array. I'm not sure how to do that in C#.

I'm using an old Windows API function in the DDEML library that requires a byte array and the number of elements in the array as arguments. If you are interested in more background, the API function is:

[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. The pSrc argument is the byte array of HSZPAIR structs. The size of the array is the cb argument.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

眉黛浅 2024-10-07 18:40:58

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

给定您的列表:

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 数组实际上只是一个字节数组。

Converting a struct to an array of bytes is kind of painful. You have to serialize it yourself. But it might not be necessary.

Given your list:

List<HSZPAIR> myList;

You can get an array by calling ToArray:

HSZPAIR[] myArray = myList.ToArray();

Now, change your managed prototype so that it takes an HSZPAIR[] rather than a byte[]:

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

That should work. After all, as you pointed out, an array of HSZPAIR really is just an array of bytes.

夢归不見 2024-10-07 18:40:58

我认为你可以使用 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;
}

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

I think you can use 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;
}

As for the list itself, it will have to be serialized separately.

<逆流佳人身旁 2024-10-07 18:40:58

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

I believe you need to define the type of the pSrc in the extern declaration as IntPtr, instead of byte[].

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文