1

ヘッダーを読み込もうとしています。構造は次のとおりです。

struct header
{
    uint32 offset;
    char identifier[4];
    uint32 unknown;
};

memcpy を介してメモリのコピーを読み取ると、オフセットを正しく (通常は大きな数値で) 出力できます。

バイト配列で組み込み関数を使用する場合、ファイル全体を読み取り、次を使用して最初の 4 バイトを取得します。

QByteArray offset = data.left(4);

次に、正しくコピーされていることを確認しました。

私の問題は、これらのバイトを適切なデータ型に変換するときです。私が試してみました:

 qDebug() << "Offset1:" << offset.toUShort();
    qDebug() << "Offset2:" << offset;
    qDebug() << "Offset3:" << offset.toHex();
    qDebug() << "Offset4:" << offset.toInt();
    qDebug() << "Offset5:" << offset.toLong();
    qDebug() << "Offset6:" << offset.toUInt();
    qDebug() << "Offset7:" << offset.toULong();
    qDebug() << "Offset8:" << offset.toULongLong();
    qDebug() << "Offset9:" << offset.toULong();

それらのどれも正しい値を出力しません。一方、memcpy だけを使用する場合:

qDebug() << "Offset:" << header.offset;

私は正しい値を取得します。バイトから uint32 への変換で何が欠けていますか?

エンディアンと関係がありますか?

4

1 に答える 1

3

toInt() などは、「100」などの文字列表現をバイナリ表現ではなく整数に変換します。バイナリを元に変換するには、キャストする必要があります。

 const quint32 v = *reinterpret_cast<const quint32*>( offset.constData() );

これはエンディアンのために脆弱であることに注意してください。構造体を含む memcpy も、構造体のアラインメント (パディング) のために安全に移植できません。より堅牢なシリアライゼーションには、QDataStreamBoost シリアライゼーションGoogle Protocol Buffersなどを使用することをお勧めします。

于 2013-01-22T08:52:51.880 に答える