2009-04-07 23 views
42

私はバイト配列にNSDataを変換したいので、私は次のコードを記述します。NSDataをiPhoneのバイト配列に変換するには?

NSData *data = [NSData dataWithContentsOfFile:filePath]; 
int len = [data length]; 
Byte byteData[len]; 
byteData = [data bytes]; 

をしかし、コードの最後の行が「割り当て中に互換性のないタイプ」というエラーがポップアップ表示されます。 データをバイト配列に変換する正しい方法は何ですか?

答えて

56

変数を使用して配列を宣言することはできません。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を回避しますが、拡張性が低くバッファオーバーフローの問題が発生しやすくなりますので、ほとんど使用しません。

+1

バイトbyteData = malloc(len); 「初期化すると、キャリブレーションなしでポインタからポインタが生成されます」という警告が表示されます。そして、byteDataはバイト配列ではなく、バイト変数であることが分かります。これについてのアイデアは? –

+0

コードに小さなタイプミスがありました。これは意図したマットとして機能するはずです。 –

+0

はい。 memcpyの第2引数は[data bytes]でなければなりません。 –

9

-[NSData bytes]の署名は- (const void *)bytesです。スタック上の配列にポインタを割り当てることはできません。 NSDataオブジェクトで管理されているバッファを配列にコピーする場合は、-[NSData getBytes:]を使用します。コピーせずにやりたい場合は、配列を割り当てないでください。ポインタ変数を宣言してNSDataがあなたのためにメモリを管理するようにしてください。

+0

私は[データGetBytesメソッドを追加した後:byteData長さ: len]; byteDataは無効であることが判明します。何が問題なのでしょうか? –

+0

NSDataを印刷して、一致するかどうかを確認してください。長さを確認し、あなたが期待しているように見えることを確認してください。データが文字列の場合は、[NSString stringWithContentsOfFile]を試すこともできます。 –

+0

私は問題を見つける:長さは変数であってはならない。これはByte byteData [255]である必要があります。 –

2

これは、[データバイト]の戻り値の型がvoid * c形式の配列であり、Uint8(Byteがtypedefである)ではないためです。長さ:あなたはリターンがポインタ型である場合に割り当てられた配列を設定しようとしているため

エラーは何を探していることはGetBytesメソッドで、ある塗りつぶし

[data getBytes:&byteData length:len]; 

:ように見えることになる呼び出しますあなたがNSDataオブジェクトからのデータで割り当てた配列。

+0

byteDataは無効です。何が問題なのでしょうか? –

+0

@ChillyZhongたとえば、 'uint8_t * cipherBuffer [16]'のようにbyteDataサイズを指定して、 '&'とNSLog(@ "%s"、(char *)byteData)を削除しようとします。 –

41

バイトをそのまま使用して、必要なタイプにキャストすることもできます。

unsigned char *bytePtr = (unsigned char *)[data bytes]; 
+0

これを行うと、「可変サイズのオブジェクトが初期化されない可能性があります」というエラーが返される –

+0

ここでも、データの最初のバイトだけがbytePtrにコピーされることがテストによって示されています。bytePtr [1]、bytePtr [2] ; –

11

はすでに答えが、他の読者を助けるために一般化する:ここで

//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]); 
    } 
0

は、私はスウィフトと同等であると考えているものです:

if let data = NSData(contentsOfFile: filePath) { 
    let length = data.length 
    let byteData = malloc(length) 
    memcmp(byteData, data.bytes, length) 
} 
関連する問題