[解決済み] C/C++のデータ構造をバイト配列からC#で読み込む
2023-03-14 04:51:24
質問
C/C++ の構造体からのデータがある場合、byte[] 配列から C# の構造体を埋める最良の方法は何でしょうか。 Cの構造体は次のようになります(私のCは非常に錆びついています)。
typedef OldStuff {
CHAR Name[8];
UInt32 User;
CHAR Location[8];
UInt32 TimeStamp;
UInt32 Sequence;
CHAR Tracking[16];
CHAR Filler[12];
}
といった具合に埋めることになる。
[StructLayout(LayoutKind.Explicit, Size = 56, Pack = 1)]
public struct NewStuff
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
[FieldOffset(0)]
public string Name;
[MarshalAs(UnmanagedType.U4)]
[FieldOffset(8)]
public uint User;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
[FieldOffset(12)]
public string Location;
[MarshalAs(UnmanagedType.U4)]
[FieldOffset(20)]
public uint TimeStamp;
[MarshalAs(UnmanagedType.U4)]
[FieldOffset(24)]
public uint Sequence;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
[FieldOffset(28)]
public string Tracking;
}
コピーするための最良の方法は何ですか?
OldStuff
を
NewStuff
であれば
OldStuff
がbyte[]配列として渡された場合?
現在、以下のようなことをしているのですが、なんとなく不格好な感じがします。
GCHandle handle;
NewStuff MyStuff;
int BufferSize = Marshal.SizeOf(typeof(NewStuff));
byte[] buff = new byte[BufferSize];
Array.Copy(SomeByteArray, 0, buff, 0, BufferSize);
handle = GCHandle.Alloc(buff, GCHandleType.Pinned);
MyStuff = (NewStuff)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(NewStuff));
handle.Free();
これを達成するためのより良い方法はあるのでしょうか?
を使用することは可能ですか?
BinaryReader
クラスを使用することで、メモリを固定した上で
Marshal.PtrStructure
?
どのように解決するのですか?
その文脈で見る限りでは、コピーする必要はありません。
SomeByteArray
をバッファにコピーする必要はありません。単にハンドルを
SomeByteArray
からハンドルを取得し、それをピン留めして
IntPtr
を使ってデータをコピーします。
PtrToStructure
を作成し、リリースします。コピーする必要はありません。
ということになりますね。
NewStuff ByteArrayToNewStuff(byte[] bytes)
{
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
try
{
NewStuff stuff = (NewStuff)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(NewStuff));
}
finally
{
handle.Free();
}
return stuff;
}
一般的なバージョンです。
T ByteArrayToStructure<T>(byte[] bytes) where T: struct
{
T stuff;
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
try
{
stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
}
finally
{
handle.Free();
}
return stuff;
}
よりシンプルなバージョン (要
unsafe
スイッチが必要)。
unsafe T ByteArrayToStructure<T>(byte[] bytes) where T : struct
{
fixed (byte* ptr = &bytes[0])
{
return (T)Marshal.PtrToStructure((IntPtr)ptr, typeof(T));
}
}
関連
-
[解決済み] エンティティタイプ ApplicationUser は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み] 'SubSonic.Schema .DatabaseColumn' 型のオブジェクトをシリアライズする際に、循環参照が検出されました。
-
[解決済み】非静的メソッドはターゲットを必要とする
-
[解決済み] 他のスレッドからGUIを更新するにはどうすればよいですか?
-
[解決済み] Pythonの辞書からキーを削除するにはどうしたらいいですか?
-
[解決済み] C#で文字列のエンコーディングを手動で指定せずに、一貫性のあるバイト表現を得るには?
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] UTF-8 byte[]を文字列に変換する方法
-
[解決済み] ストリームからのバイト配列の作成
-
[解決済み] .NETでapp.configやweb.configから設定を読み込む
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】エラー。「戻り値を変更できません」 C#
-
[解決済み] エンティティタイプ ApplicationUser は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み】「入力文字列が正しい形式ではありませんでした」エラーの解決方法は?[重複しています]。
-
[解決済み】クロススレッド操作が有効でない。作成されたスレッド以外のスレッドからアクセスされたコントロール
-
[解決済み] [Solved] アセンブリ System.Web.Extensions dll はどこにありますか?
-
[解決済み】C# - パスに不正な文字がある場合
-
[解決済み】HRESULTからの例外:0x800A03ECエラー
-
[解決済み】画像のペイントにTextureBrushを使用する方法
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である