2010-09-30 22 views
6

Bu, this posting'a kadar olan bir izlemedir ancak farklı bir soruyla ayrı bir iş parçacığından sormam gerektiğini hissettim.Bir NSInteger veya NSUInteger nesnesinin bayt sırasını nasıl tersine çevirebilirim?

Bir dosyadan okuduğum bellekte dört ardışık baytım olduğu noktadayım. Bunları bir bit dizisi olarak saklamak istiyorum (bunların gerçek int değeri daha sonraya kadar önemli değildir). Int'mdeki şeyi yazdığımda, ters sırada (küçük endian) saklandığını fark ettim.

Herhangi birinin, baytların sırasını tersine çevirmek için iyi bir yöntemi var mı. Sonra bir kez tersine, iki bayt kapsayan ardışık bitleri seçip bir int dönüşüyor?

unsigned char data[] = { 0x00, 0x02, 0x45, 0x28 }; 
NSInteger intData = *((NSInteger *)data); 

NSLog(@"data:%08x", intData); // data:28450200 

cevap

15

Kakao (veya tam Hazırlık çerçeve olmak üzere) bayt endian değiş tokuş etmek için işlevleri vardır: NSSwapInt, NSSwapShort, NSSwapLong ve NSSwapLongLong. Bunlar baytların etrafında ne olursa olsun, küçük-enduslu tam sayılardan büyük-ender tamsayılar yaparlar ya da tersini yaparlar.

Hangi biçime sahip olduğunuzu biliyorsanız, bunu yerel endianiteye geçiren başka işlevler de vardır: NSSwapLittleIntToHost ve NSSwapBigIntToHost. Ayrıca yerel formattan küçük veya büyük endian formatına geçiş yapan ters fonksiyonlar da vardır: NSSwapHostIntToLittle ve NSSwapHostIntToBig. Bunlar diğer tamsayı türleri ve kayan nokta türleri için de kullanılabilir. Yaptıkları şey, eğer gerekliyse ilkel takas işlevlerini değerler üzerinde çağırmalarıdır. Bu nedenle NSSwapLittleIntToHost, hiçbir şey yapmazken NSSwapBigIntToHost, küçük bir endian makinesinde NSSwapInt sonucunu döndürür.

Bu, derleyici tamsayı türlerinin NSInteger türünde parametre almadığını unutmayın. Dolayısıyla, 32bit veya 64bit kodu oluşturuyor olmanıza bağlı olarak, NSInteger kullanıyorsanız farklı işlevler kullanmanız gerekir.

Ayrıca, bayt dizisini bir tamsayı işaretçisine ve buna uygun olmayan dizine atmamalısınız. Bit kaydırma işlemlerini kullanarak tamsayıyı birleştirmek daha iyi olurdu. Kodunuz sadece NSInteger 32 bit genişliğinde çalışır. 64 bit ise, numaranız çöp olacaktır veya programınız çökebilir. Ancak her zaman 32 bit genişlikte bir tamsayı türü (örneğin, C99 <stdint.h> başlığından int32_t) kullanıyorsanız, bu beklendiği gibi çalışmayabilir.

+0

NSSwapBigIntToHost'u bulamıyordum. Önerdiğin gibi biraz daha az manipülasyon yapıyordum. Kodlarımda benim in-line'lerin 32-bit olacağını varsayıyorum. Yaptığım şey, imzalanmamış bir char * tref = (imzasız char *) yaratıyordu. &temp; Daha sonra bayttan geçip baytları değiştirdim, sonra tref'i bir tamsayıya dönüştürdüm. Güzel değil ama 32-bit olduğum sürece çalışıyor. – Scott

+0

harika bir soru ve cevap – LolaRun

İlgili konular