2

BinaryWriterクラスを使用してC#でバイナリファイルを書き込んでいます

using (var b = new System.IO.BinaryWriter(System.IO.File.Open("C:\\TextureAtlas0.txa", 
       System.IO.FileMode.Create)))
{
  int count;

  // Write the number of source rectangle entries
  count = textureAtlas.Rectangles.Count;

  b.Write(count);

  for (int i = 0; i < count; ++i)
  {
    b.Write(textureAtlas.SpriteNames[i]);
    b.Write(textureAtlas.Rectangles[i].X);
    b.Write(textureAtlas.Rectangles[i].Y);
    b.Write(textureAtlas.Rectangles[i].Width);
    b.Write(textureAtlas.Rectangles[i].Height);
  }
}

次に、次の手順を使用して、同じファイルをC++に読み込んでみます。

書き込まれたのと同じ順序でデータを保持する構造体があります。

struct TextureAtlasEntry 
{
    std::string name;
    int x;
    int y;
    int width;
    int height;
};

カウントが最初に読み取られます

int count;

fread(&count, sizeof(int), 1, LoadFile);

次に、カウント値を使用して、データを保持するリストサイズを決定しようとします。読み取るファイルによってcountの値が異なるため、配列を使用できないようです。

std::list<TextureAtlasEntry> entries;
fread(&entries, sizeof(TextureAtlasEntry), count, LoadFile);

fclose(LoadFile);

上記のコードは機能しません。カウントを正しく読み取ることができますが、memcpyコマンドにより、freadとエントリリストでアクセス違反が発生します。

データを正しく読み取るにはどうすればよいですか?Freadを同等のC ++と交換する必要がありますか?

編集:

次のコードを使用して、バイナリファイル全体をメモリに読み込むことができます

ifstream::pos_type size;
char *memblock;

ifstream file ("TextureAtlas0.txa", ios::in|ios::binary|ios::ate);

if (file.is_open())
{
    size = file.tellg();
    memblock = new char[size];
    file.seekg (0, ios::beg);
    file.read (memblock, size);
    file.close();

    printf("File content is in memory");

    delete[] memblock;
}
else 
{
    printf("Unable to open file");
}

これでファイルがメモリに保存されました。char[]データを構造体データに変換するにはどうすればよいですか?

4

2 に答える 2

2

ドキュメントによると、 BinaryWriter(String) は書き込みます...

長さがプレフィックスされた文字列は、その文字列の長さを含む単一のバイトまたは単語を文字列にプレフィックスとして付けることによって、文字列の長さを表します。このメソッドは、最初に文字列の長さを UTF-7 でエンコードされた符号なし整数として書き込み、次に BinaryWriter インスタンスの現在のエンコーディングを使用して、その文字数をストリームに書き込みます。

C++ コードでは、構造体のサイズのバイト数を読み込もうとしていますが、これは BinaryWriter が使用する形式とは異なります。

C++ コードに .NET を使用していますか? その場合は、代わりに BinaryReader クラスを使用してファイルを読み込みます。

そうでない場合は、読み取りを少し分割する必要があります。名前を読み取る準備ができたら、まず「UTF-7 でエンコードされた符号なし整数」を読み取ってから、さらに多くのバイトを読み取って文字列を取得する必要があります。

編集

以下のコメントに基づいて、C++.NET を使用しないと思われるので、2 つのオプションがあると思います。1) C++ に読み込めるように C# でデータを書き出す (固定長文字列を使用) 2) BinaryWriter.Write() がデータを書き出す方法を理解して、C++ で正しく読み込めるようにする

疑似コード - このようなものだと思います。以下のコメントで述べたように、私の C++ は錆びていますが、これは基本的なアルゴリズムに近いはずです。

read from file int num - number of items
for (i=0;i<num;i++){
   read int stringBytes - size of string
   read string stringBytes bytes - the name
   read int X4
   create your struct and add to list/array/dictionary
}
于 2012-09-06T23:07:59.243 に答える
0

別の回答で説明されている文字列データ型の問題ではなく、もう1つここにあります。std::listdoubly linked list本質的に追加のポインタを含むため、directfread/memcpyはおそらくc#スニペットに保存したものを提供しません。

于 2012-09-06T23:10:55.933 に答える