使用C#获取Int/short/byte结构的字节表示形式 [英] getting an Int/short/byte structure byte representation with C#

查看:287
本文介绍了使用C#获取Int/short/byte结构的字节表示形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个FieldInfo对象和一个对象,我需要获取该字段的实际字节表示形式.我知道该字段是int,Int32,uint,short

Given a FieldInfo object and an object, I need to get the actual bytes representation of the field. I know that the field is either int,Int32,uint,short etc.

如何获取实际的字节表示形式? BinaryFormatter.Serialize将无济于事,因为它会为我提供比我所需更多的信息(它还会记录类型名称等). Marshal类似乎没有使用字节数组的功能(但也许我缺少了一些东西).

How can I get the actual byte representation? BinaryFormatter.Serialize won't help, since it'll give me more information than I need (it also records type name etc.). The Marshal class does not seem to have facilities to use bytes array (but maybe I'm missing something).

谢谢

推荐答案

如果您实际想要的是将结构作为字节数组传输,则也可以尝试以下代码:

You may also try code like the following if what you actually want is to transfer structures as a byte array:

int rawsize = Marshal.SizeOf(value);
byte[] rawdata = new byte[rawsize];
GCHandle handle = GCHandle.Alloc(rawdata, GCHandleType.Pinned);
Marshal.StructureToPtr(value, handle.AddrOfPinnedObject(), false);
handle.Free();

这会将给定的对象 value 转换为字节数组rawdata.我从我先前编写的代码中获取了此信息,您可能需要对其进行调整以使其真正起作用.我将其用于与某些具有用户定义结构的硬件进行通信,但它也应适用于内置类型(毕竟它们是结构,不是吗?)

This converts the given object value to the byte array rawdata. I've taken this from code I previously wrote, and you may need to adapt it to your needs to make it actually work. I used it for communication with some hardware with user-defined structures, but it should work for built-in types as well (after all, they're structures, aren't they?)

要使结构成员正确对齐,请使用StructLayout属性指定一字节对齐:

To make structure members properly aligned, use the StructLayout attribute to specify one-byte-alignment:

[StructLayout(LayoutKind.Sequential, Pack = 1)]

然后根据需要为字段使用MarshalAs属性,例如对于内联数组:

And then use the MarshalAs attribute as needed for fields, e.g. for inline arrays:

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
byte[] _state;

从字节数组中获取结构的代码如下:

The code to get the structure back from the byte array is something like this:

public T GetValue<T>()
{
    GCHandle handle = GCHandle.Alloc(RawValue, GCHandleType.Pinned);
    T structure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), 
                      typeof(T));
    handle.Free();
    return structure;
}

当然,您需要知道要使其工作的类型.

Of course you'll need to know the type you want for this to work.

请注意,这不会自行处理字节序.在我的项目中,大多数字段只是一个字节,所以没关系,但是对于少数几个字段,我只是将这些字段设为私有并添加了公共属性,以照顾字节序(

Note that this will not handle endianness for itself. In my project, most fields were one byte only, so it didn't matter, but for the few fields where it did, I just made the fields private and added public properties that would take care of the endianness (Jon Skeet's link from a comment to his answer may help you, I wrote some utility functions for this since I needed only few).

当我需要此代码时,我创建了一个Message类,该类将存储原始值(因此,使用GetValue方法,顶部的代码实际上是SetValue方法的主体),并具有一些方便的方法来格式化值等

When I needed this, I created a Message class that would store the raw value (hence the GetValue method, the code at the top is actually the body of a SetValue method) and had some nice convenience method to get the value formatted etc.

这篇关于使用C#获取Int/short/byte结构的字节表示形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆