简体   繁体   English

如何在C#中创建固定大小的字节数组用户类型?

[英]How do I make fixed-size byte array user type in C#?

I'm converting an old Visual BASIC program to C#. 我正在将旧的Visual BASIC程序转换为C#。 It sends messages to some industrial machinery over ethernet. 它通过以太网向一些工业机器发送消息。 To do this it assembles a stream of bytes from fixed-size user defined chunks. 为此,它从固定大小的用户定义的块组装一个字节流。

Most of these chunks are small and in C# it's easy to create structs of a few bytes or ints and control their size and layout using StructLayout's, for example 大多数这些块都很小,在C#中很容易创建几个字节或整数的结构,并使用StructLayout控制它们的大小和布局,例如

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

...so when we go into unmanaged space to do a bytewise copy we don't have byte order or padding problems. ...所以当我们进入非托管空间进行逐字节复制时,我们没有字节顺序或填充问题。

But some of the VB6 structures are big arrays, for example, 但是一些VB6结构是大型数组,例如,

Private Type SEND_MSG_BUFFER_320_BYTES
    bytes(0 To 319) As Byte  '320 bytes
End Type

and I'm struggling with how to do this in C#. 我正在努力解决如何在C#中做到这一点。 I can make a fixed size array in a class, eg, 我可以在类中创建一个固定大小的数组,例如

  [StructLayout(LayoutKind.Sequential, Pack = 1)]
  public class SOME_BYTES
  {
      public byte[] b = new byte[320];
  } 

but to do the byte-wise copy I need to be able to discover the size of this at runtime and System.Runtime.InteropServices.Marshal.SizeOf returns a 4 for this. 但要执行逐字节复制,我需要能够在运行时发现它的大小,System.Runtime.InteropServices.Marshal.SizeOf为此返回4

Any suggestions for how do do this will be much appreciated. 任何有关如何做到这一点的建议将不胜感激。

You can use fixed size buffers if you're okay with unsafe code, and changing your class into a struct: 如果您对不安全的代码没问题,并将类更改为结构,则可以使用固定大小的缓冲区

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct SomeBytes
{
    public fixed byte MessageData[320];
}

Personally I would try to avoid all of this if possible. 就个人而言,如果可能,我会尽量避免所有这些。 If you're just sending the data over the network, why do you need to "go into unmanaged space"? 如果您只是通过网络发送数据,为什么还需要“进入非托管空间”? Can you remove that requirement somehow? 你能以某种方式删除该要求吗? (Maybe it's fundamental - but it's not clear from your question.) (也许这是根本性的 - 但是你的问题并不清楚。)

You can use a fixed-size array: 您可以使用固定大小的数组:

unsafe struct SomeBytes {
    public fixed byte b[320];
}

I think you want to do something like this: 我想你想做这样的事情:

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public class SOME_BYTES
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst=320)]
        public byte[] b;
    } 

You would initialise it as follows: 您可以按如下方式初始化它:

SOME_BYTES data = new SOME_BYTES {b = new byte[320]};

Then you can populate data.b[] and use marshalling to get the data to send. 然后你可以填充data.b []并使用编组来获取要发送的数据。 The MarshalAs attribute tells the marshaller what fixed size buffer to use when marshalling the data. MarshalAs属性告诉编组程序在编组数据时要使用的固定大小缓冲区。

You don't need to use the unsafe fixed keyword to do this kind of thing, and I strongly recommend that you avoid it. 您不需要使用不安全的fixed关键字来执行此类操作,我强烈建议您避免使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM