NSData
をバイト配列に変換したいので、次のコードを記述します。
NSData *data = [NSData dataWithContentsOfFile:filePath];
int len = [data length];
Byte byteData[len];
byteData = [data bytes];
しかし、コードの最後の行には、「割り当ての互換性のないタイプ」というエラーが表示されます。データをバイト配列に変換する正しい方法は何ですか?
変数を使用して配列を宣言できないため、_Byte byteData[len];
_は機能しません。ポインターからデータをコピーする場合は、memcpyも必要です(ポインターが指すデータを通過し、指定された長さまで各バイトをコピーします)。
試してください:
_NSData *data = [NSData dataWithContentsOfFile:filePath];
NSUInteger len = [data length];
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, [data bytes], len);
_
このコードは、配列を適切なサイズに動的に割り当て(完了したらfree(byteData)
する必要があります)、そこにバイトをコピーします。
固定長配列を使用する場合は、他のユーザーが示すように_getBytes:length:
_を使用することもできます。これにより、malloc/freeは回避されますが、拡張性が低く、バッファオーバーフローの問題が発生しやすいため、めったに使用しません。
また、必要な型にキャストして、バイトを使用することもできます。
unsigned char *bytePtr = (unsigned char *)[data bytes];
すでに答えましたが、他の読者を助けるために一般化するには:
//Here: NSData * fileData;
uint8_t * bytePtr = (uint8_t * )[fileData bytes];
// Here, For getting individual bytes from fileData, uint8_t is used.
// You may choose any other data type per your need, eg. uint16, int32, char, uchar, ... .
// Make sure, fileData has atleast number of bytes that a single byte chunk would need. eg. for int32, fileData length must be > 4 bytes. Makes sense ?
// Now, if you want to access whole data (fileData) as an array of uint8_t
NSInteger totalData = [fileData length] / sizeof(uint8_t);
for (int i = 0 ; i < totalData; i ++)
{
NSLog(@"data byte chunk : %x", bytePtr[i]);
}
_-[NSData bytes]
_の署名は- (const void *)bytes
です。スタック上の配列にポインターを割り当てることはできません。 NSData
オブジェクトで管理されているバッファーを配列にコピーする場合は、_-[NSData getBytes:]
_を使用します。コピーせずに実行したい場合は、配列を割り当てないでください。ポインタ変数を宣言し、NSData
にメモリを管理させるだけです。
これは、[データバイト]の戻り値の型がUint8(Byteのtypedefである)ではなく、void * cスタイルの配列だからです。
エラーは、戻り値がポインター型であるときに割り当てられた配列を設定しようとしているため、探しているのは、次のようなgetBytes:length:呼び出しです。
[data getBytes:&byteData length:len];
NSDataオブジェクトからのデータで割り当てた配列を埋めます。
Swiftに相当するものだと私は信じています:
if let data = NSData(contentsOfFile: filePath) {
let length = data.length
let byteData = malloc(length)
memcmp(byteData, data.bytes, length)
}