投稿者 魔界の仮面弁士  (社会人) 投稿日時 2022/10/18 22:01:38
string を含む構造体では、 StructLayout に Charset も明示すべきです。
また、Pack も明示的に指定する必要があります。

// Marshal.SizeOf<usrData>() が返す構造体サイズ
[StructLayout(LayoutKind.Sequential)]  // 528
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)]  // 524
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 8)]   // 1040



> //ファイルのバイト長だけバイト配列を作成
> byte[] bs = new byte[fs.Length];
一括読み込みするのであれば、File.ReadAllBytes() では駄目でしょうか?
ReadAllBytes は、FileMode.Open, FileAccess.Read, FileShare.Read 相当の
FileStream 操作なので、コードがスッキリするかと思います。

fs.Read を繰り返す形にするのは、一括読み取りする場合では無く、
レコード単位など、ある程度のブロック単位に区切って順次読み取っていくような場面です。


> Mydata = (Form1.usrData)Marshal.PtrToStructure(ptr, typeof(Form1.usrData));
.NET Framework 4.5.1 以降では
 Mydata = Marshal.PtrToStructure<Form1.usrData>(ptr);
を使った方が良いですよ。


> ※ 3件のデータが有りますが、1件読んで終わってしまいます。
これは単純に、繰り返している箇所が無いからですね。

for + break; している箇所があるものの、
 「全部読みだす」→「ループ二回目では読み取り済みなので break」
という操作になっているだけで、データ件数 3 回分繰り返す実装にはなっていません。


ファイル全体のサイズは fs.Length だとして、
構造体一つの大きさは Marshal.SizeOf<usrData>() で取得できますので、
 (案1) ファイル長をレコード長で割った回数、繰り返し Copy する
 (案2) レコード長単位で Read しては Copy する処理を、Read した長さが不足するまで繰り返す
のいずれかにしてみては如何でしょうか。