11

古いVisualBASICプログラムをC#に変換しています。イーサネットを介して一部の産業機械にメッセージを送信します。これを行うために、固定サイズのユーザー定義チャンクからバイトのストリームをアセンブルします。

これらのチャンクのほとんどは小さく、C#では、たとえばStructLayoutを使用して、数バイトまたはintの構造体を作成し、それらのサイズとレイアウトを制御するのは簡単です。

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

...したがって、バイト単位のコピーを実行するためにアンマネージスペースに入る場合、バイト順序やパディングの問題は発生しません。

ただし、VB6構造の一部は大きなアレイです。たとえば、

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

そして私はC#でこれを行う方法に苦労しています。クラスで固定サイズの配列を作成できます。たとえば、

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

しかし、バイト単位のコピーを行うには、実行時にこれのサイズを検出できる必要があり、System.Runtime.InteropServices.Marshal.SizeOfはこれに対して4を返します。

これをどのように行うかについての提案は大歓迎です。

4

3 に答える 3

14

安全でないコードに問題がなく、クラスを構造体に変更する場合は、固定サイズのバッファーを使用できます。

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

個人的には、可能であれば、これらすべてを避けようとします。ネットワーク経由でデータを送信するだけの場合、なぜ「管理されていないスペースに入る」必要があるのでしょうか。どういうわけかその要件を削除できますか?(多分それは基本的なことですが、あなたの質問からは明らかではありません。)

于 2013-01-31T15:12:24.853 に答える
11

固定サイズの配列を使用できます。

unsafe struct SomeBytes {
    public fixed byte b[320];
}
于 2013-01-31T15:12:11.363 に答える
9

私はあなたがこのようなことをしたいと思います:

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

次のように初期化します。

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

次に、data.b []にデータを入力し、マーシャリングを使用して送信するデータを取得できます。MarshalAs属性は、データをマーシャリングするときに使用する固定サイズのバッファーをマーシャラーに指示します。

この種のことを行うために安全でないfixedキーワードを使用する必要はないので、避けることを強くお勧めします。

于 2013-01-31T15:19:02.880 に答える