【发布时间】:2013-02-04 17:06:41
【问题描述】:
我正在修改的一些代码广泛使用结构来与某些工厂设备进行通信,方法是将它们加载到字节数组或从字节数组加载。
这是一个这样的结构的超级简化示例。
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct K_FOO
{
public byte a_byte; // 1 byte
public BYTE3_TYPE b3; // 3 bytes
public int num; // happens to be 4 bytes
}
BYTE3_TYPE 看起来像这样...
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class BYTE3_TYPE
{
[System.Runtime.InteropServices.MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] L = new byte[3];
}
如果我只是做一个
K_FOO origFoo = new K_FOO();
int 和 byte 被初始化为 0,我假设是因为它们是原生类型,但字节数组 b3 是 *un*initialized - 全部为空。我必须显式加载它,例如,
BYTE3_TYPE b3 = new BYTE3_TYPE();
origFoo.b3 = b3;
...我想不出任何替代方案,因为结构不采用无参数构造函数,但真正的结构很大。
但我注意到了一些有趣的事情。我们有例程将这些结构复制到字节数组和从字节数组复制。例如 。 . .
public static T ByteArrayToStructure<T>(byte[] buffer) where T : struct
{
int length = buffer.Length;
IntPtr ptr = Marshal.AllocHGlobal(length); // allocate (length) bytes
Marshal.Copy(buffer, 0, ptr, length); // copies into UNmanaged space
T result = (T)Marshal.PtrToStructure(ptr, typeof(T));
Marshal.FreeHGlobal(ptr);
return result;
}
...如果我称它为...
K_FOO retFoo = ByteArrayToStructure<K_FOO>(buffer.bytes);
...返回的结果结构完全初始化,字节数组中的字节都已分配空间,因此可以加载它们,显然是在 PtrToStructure() 调用中。这意味着.Net“知道”如何初始化这样的结构。那么有没有办法让 .Net 为我做到这一点,这样我就可以避免编写数百行显式初始化代码?提前致谢!
【问题讨论】:
标签: c#