2010-09-30 38 views
6

Đây là phần theo dõi this posting nhưng với một câu hỏi khác nên tôi cảm thấy tôi nên hỏi trong một chuỗi riêng biệt.Làm thế nào tôi có thể đảo ngược thứ tự byte của NSInteger hoặc NSUInteger trong mục tiêu-c

Tôi đang ở điểm mà tôi có bốn byte liên tiếp trong bộ nhớ mà tôi đã đọc từ một tệp. Tôi muốn lưu trữ chúng như là một mảng bit (giá trị int thực tế của chúng không quan trọng cho đến sau này). Khi tôi in ra những gì trong int của tôi, tôi nhận thấy rằng nó dường như được lưu trữ theo thứ tự ngược lại (ít endian).

Có ai có phương pháp tốt để đảo ngược thứ tự các byte không. Sau đó, một khi đảo ngược, chọn ra các bit liên tiếp kéo dài hai byte và chuyển đổi trở lại một int?

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

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

Trả lời

15

Cocoa (hoặc để được chính xác khuôn khổ Foundation) có chức năng để trao đổi các endianness byte: NSSwapInt, NSSwapShort, NSSwapLong, và NSSwapLongLong. Những sự trao đổi xung quanh các byte không có vấn đề gì - chúng tạo ra các số nguyên lớn từ các số nguyên nhỏ và ngược lại.

Nếu bạn biết định dạng nào bạn có ở đó là các chức năng khác trao đổi với độ dài gốc: NSSwapLittleIntToHostNSSwapBigIntToHost. Ngoài ra còn có các chức năng đảo ngược thay đổi từ định dạng gốc thành định dạng cuối nhỏ hoặc lớn: NSSwapHostIntToLittleNSSwapHostIntToBig. Chúng có sẵn cho các kiểu số nguyên khác và kiểu dấu phẩy động. Những gì họ làm là họ gọi các hàm hoán đổi nguyên thủy trên các giá trị nếu cần thiết. Vì vậy, NSSwapLittleIntToHost không làm bất cứ điều gì trong khi NSSwapBigIntToHost trả lại kết quả của NSSwapInt trên một máy cuối nhỏ.

Lưu ý rằng các thông số lấy này của các loại số nguyên trình biên dịch chứ không phải loại NSInteger. Vì vậy, tùy thuộc vào thời điểm bạn tạo mã 32 bit hoặc 64 bit, bạn phải sử dụng các chức năng khác nhau nếu bạn đang sử dụng NSInteger.

Bạn cũng không nên bỏ mảng byte của bạn đến một con trỏ nguyên và dereference đó. Nó sẽ là tốt hơn để lắp ráp các số nguyên bằng cách sử dụng các hoạt động thay đổi bit. Mã của bạn sẽ chỉ hoạt động nếu NSInteger rộng 32 bit. Nếu nó là 64 bit thì số của bạn sẽ là rác hoặc chương trình của bạn thậm chí có thể sụp đổ. Nhưng ngay cả khi bạn đang sử dụng loại số nguyên luôn rộng 32 bit (ví dụ: int32_t từ tiêu đề C99 <stdint.h>) thì điều này có thể không hoạt động như mong đợi.

+0

Cảm ơn tôi đã xem xét một chút và không tìm thấy NSSwapBigIntToHost. Tôi đã kết thúc một số thao tác bit thấp hơn như bạn đã đề xuất. Tôi đang làm một chút của một giả định rằng ints của tôi sẽ được 32-bit trong mã của tôi. Những gì tôi đã kết thúc làm là tạo ra một unsigned char * tref = (unsigned char *) &temp; Tôi sau đó lặp qua và trao đổi các byte, sau đó đúc tref đến một số nguyên. Không đẹp nhưng hoạt động miễn là tôi ở 32-bit. – Scott

+0

câu hỏi và câu trả lời tuyệt vời – LolaRun

Các vấn đề liên quan