2016-04-25 16 views
-2

MIDIファイルを作成するプログラムを作成しています。ファイルにMIDIメッセージを書き込もうとしています。C/C++の正しい方法でファイルにバイトを書き込む[Endianess]

まず、関数fputc()を使用してゼロからファイルを作成し、バイトごとにすべてのファイルを入力する方法をテストしたところ、うまくいっていました。私は、同時に1バイト以上を書き込みしようとしたときに機能fwrite()が後方にバイトを置くため

問題は、(例えば、ファイルにshort intまたはintを書いて)来ました。例えば

FILE* midiFile; 

midiFile = fopen("test.mid", "wb"); 

short msg = 0x0006; 

fwrite(msg, sizeof(msg), 1, midiFile); 

fclose(midifile); 

出力をファイルint型の0x06には0x00を書き込んだ、と予想されなかっ:0x00,0x06。

私はこれを読んで、エンディアンの原因であることがわかりました;私のIntelプロセッサはリトルエンディアンを使用しているので、変数を1バイトのより後ろに書き出します(ビックエンディアンマシンと比較して)。

私はまだそれを修正し、私のプログラムを開発する方法でバイトを書く必要があります。

htonl()または類似のような機能を特定していない私のコンパイラは、(私はなぜ知らない)が、私はそれを行うために、またはどのように特に(short年代とint 'はchar配列のSを書くための方法を求めていますshortのもの)。

+0

を使用すると、その "C/C++" 言語の仕様へのリンクを提供することができない限り、C **や** C++のいずれかを選択してください。彼らは異なる言語です!また、コードに潜在的な問題もあります。内部データを転送/格納するには、_marshalling_を適切に使用し、_fixed size_の型を使用します。 – Olaf

+1

@Olaf、この特定のケースでは、答えは同じになるので、cとC++タグは適切です。それ以外の場合は、その質問に対して複数のタグが許可されているとは限りません。 – SergeyA

+0

@ SergeyA:意見が分かりません。適切なマーシャリングは、CおよびC++で非常に異なる実装が必要なOOPアプローチを使用すると、大幅に単純化できます。 – Olaf

答えて

0

のどちらか、順番に一つずつ...

をしたいバイトを書き込み、またはあなたがそれらを書く前にバイトを交換します。

バイトのスワップ
uint8_t msbyte = msg >> 8; 
uint8_t lsbyte = msg & 0xFF; 

uint8_t buffer[2]; 
// Big Endian 
buffer[0] = msbyte; 
buffer[1] = lsbyte; 

/* Little endian 
buffer[0] = lsbyte; 
buffer[1] = msbyte; 
*/ 
fwrite(&buffer[0], 1, sizeof(buffer), midiFile); 

uint16_t swap_bytes(const uint16_t value) 
{ 
    uint16_t result; 
    result = value >> 8; 
    result += (value & 0xFF) << 8; 
    return result; 
} 
関連する問題