質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

15941閲覧

構造体をファイルに保存、読み込みしたい。

pikumin001

総合スコア132

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

2クリップ

投稿2017/08/16 13:39

編集2017/08/16 13:40

タイトル通りなのですが、Form1で以下のような構造体を作り、保存することまではできました。

form1

c#

1public struct summonerData 2 { 3 string name; 4 string id; 5 string accountID; 6 string profileIconID; 7 long revisionDate; 8 int summonerLevel; 9 public summonerData(string ID, string AccountID, string Name, string ProfileIconID,long RevisionData,int SummonerLevel) 10 { 11 name = Name; 12 id = ID; 13 accountID = AccountID; 14 profileIconID = ProfileIconID; 15 revisionDate = RevisionData; 16 summonerLevel = SummonerLevel; 17 } 18 19public summonerData MyData;

c#

1 public class dataSave 2 { 3 string dataPath = System.IO.Directory.GetCurrentDirectory() + @"\data\"; 4 5 public void MydataSave(Form1.summonerData Mydata) 6 { 7 int size = Marshal.SizeOf(Mydata); 8 byte[] by = new byte[size]; 9 IntPtr ptr = Marshal.AllocHGlobal(size); 10 11 //マネージオブジェクトからアンマネージメモリにデータをマーシャリング 12 Marshal.StructureToPtr(Mydata, ptr, false); 13 14 //アンマネージデータをマネージのbyte[]にコピーする 15 Marshal.Copy(ptr, by, 0, size); 16 Marshal.FreeHGlobal(ptr); 17 18 System.IO.DirectoryInfo di =System.IO.Directory.CreateDirectory(dataPath); 19 System.IO.FileStream fs = new System.IO.FileStream(dataPath + "Mydata.data",System.IO.FileMode.Create,System.IO.FileAccess.Write); 20 //バイト型配列の内容をすべて書き込む 21 fs.Write(by, 0, by.Length); 22 //閉じる 23 fs.Close(); 24 } 25 26 public Form1.summonerData MydataLoad() 27 { 28 System.IO.FileStream fs = new System.IO.FileStream(dataPath +"Mydata.data" ,System.IO.FileMode.Open,System.IO.FileAccess.Read); 29 30 //ファイルのバイト長だけバイト配列を作成 31 byte[] bs = new byte[fs.Length]; 32 //ファイルの内容をすべて読み込む 33 fs.Read(bs, 0, bs.Length); 34 35 36 37 Form1.summonerData Mydata; 38 39 int size = bs.Length; 40 IntPtr ptr = Marshal.AllocHGlobal(size); 41 Marshal.Copy(bs, 0, ptr, size); 42 Mydata = (Form1.summonerData)Marshal.PtrToStructure(ptr, typeof(Form1.summonerData)); 43 Marshal.FreeHGlobal(ptr); 44 45 46 fs.Close(); 47 48 return Mydata; 49 50 } 51 52 }

MyDataという構造体にデータを入力後、MydataSave MydataLoadでバイナリに変換し、読み書きを行おうとしたのですが、
アプリ起動→データを保存→読み込み ということは可能。
アプリ起動→データの読み込み エラーという現象が起こっています。(もちろん保存データのファイルがある状態で)
エラー内容と箇所は
Mydata = (Form1.summonerData)Marshal.PtrToStructure(ptr, typeof(Form1.summonerData));
型 'System.AccessViolationException' のハンドルされていない例外が mscorlib.dll で発生しました
追加情報:保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。

アプリ起動中に保存してから読み込みは可能なのにアプリ終了後に読み込もうとすると、エラーが出るのがちょっと納得出来ないのですが、なぜなのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

C# の string はオブジェクトなのでそのままマーシャルする事は出来ません。

構造体のフィールドに、マーシャルされる際の型とサイズを定義する必要があります。

csharp

1[StructLayout(LayoutKind.Sequential)] // フィールドを順にシリアライズ 2public struct summonerData 3 { 4 [MarshalAs(UnmanagedType.ByValTStr,SizeConst=128)] 5 string name; 6 [MarshalAs(UnmanagedType.ByValTStr,SizeConst=128)] 7 string id; 8 [MarshalAs(UnmanagedType.ByValTStr,SizeConst=128)] 9 string accountID; 10 [MarshalAs(UnmanagedType.ByValTStr,SizeConst=128)] 11 string profileIconID; 12 long revisionDate; 13 int summonerLevel; 14 public summonerData(string ID, string AccountID, string Name, string ProfileIconID,long RevisionData,int SummonerLevel) 15 { 16 name = Name; 17 id = ID; 18 accountID = AccountID; 19 profileIconID = ProfileIconID; 20 revisionDate = RevisionData; 21 summonerLevel = SummonerLevel; 22 }

サイズは必要に応じて変更下さい。

投稿2017/08/16 16:08

mattn

総合スコア5030

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pikumin001

2017/08/16 16:13

なるほど、そういうことだったのですか。 マーシャルや構造体を使ったことがないので知りませんでした、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問