c語言結(jié)構(gòu)體在 ios藍(lán)牙socket協(xié)議的妙用

ios中不一定需要c構(gòu)建協(xié)議。但是總體來說用c語言來說相對對數(shù)據(jù)處理友好方便一些咬腋,不像oc那樣笨重羹膳,畢竟c是做底層的。但是用了c處理有時候需要考慮內(nèi)存釋放問題根竿。話不多說陵像。湃缎。。

如果某些協(xié)議中只出現(xiàn)8位的數(shù)據(jù)蠢壹,這種是相對最好處理的嗓违。例如:

如下協(xié)議:

可以構(gòu)建:

typedef struct{

????uint8_t head;

? ? uint8_t data_1;

? ? uint8_t data_2;

? ? uint8_t place[2];

? ? uint8_t check;

? ? uint8_t tail;

}Test_struct;

對于這種類型的數(shù)據(jù)要轉(zhuǎn)成oc的NSdata對象可用

Test_struct struct_data_context;

NSData *data = [NSData dataWithBytes:&struct_data_context length:sizeof(Test_struct)];

那么NSdata轉(zhuǎn)該類型的結(jié)構(gòu)體可用

Test_struct test_struct_data ;

[data getBytes:&test_struct_data length:sizeof(Test_struct)];

是不是很簡單图贸?不用一個一個賦值了蹂季!


但是。疏日。偿洁。如果數(shù)據(jù)中存在16位數(shù)據(jù) (數(shù)據(jù)分高低8位)這種情況下需要注意一下幾點

1.數(shù)據(jù)大小端

2.結(jié)構(gòu)體對齊(

原則1、數(shù)據(jù)成員對齊規(guī)則:結(jié)構(gòu)(struct或聯(lián)合union)的數(shù)據(jù)成員沟优,第一個數(shù)據(jù)成員放在offset為0的地方涕滋,以后每個數(shù)據(jù)成員存儲的起始位置要從該成員大小的整數(shù)倍開始(比如int在32位機為4字節(jié),則要從4的整數(shù)倍地址開始存儲)挠阁。

原則2宾肺、結(jié)構(gòu)體作為成員:如果一個結(jié)構(gòu)里有某些結(jié)構(gòu)體成員,則結(jié)構(gòu)體成員要從其內(nèi)部最大元素大小的整數(shù)倍地址開始存儲侵俗。(struct a里存有struct b锨用,b里有char,int隘谣,double等元素增拥,那b應(yīng)該從8的整數(shù)倍開始存儲。)

原則3寻歧、收尾工作:結(jié)構(gòu)體的總大小掌栅,也就是sizeof的結(jié)果,必須是其內(nèi)部最大成員的整數(shù)倍码泛,不足的要補齊猾封。

)詳細(xì)的后面會提到

例如:以下協(xié)議格式(小端)

我們可以這樣構(gòu)建結(jié)構(gòu)體,

typedef struct{????uint8_t head;? ? uint8_t data_1; ? uint16_t data;? ? uint8_t place[2];? ? uint8_t check;? ? uint8_t tail;}Test_struct;

注意刪除線弟晚。對于16位數(shù)據(jù)小端處理的數(shù)據(jù)忘衍,(上表第3第4字節(jié))ios 處理器arm架構(gòu) 默認(rèn)處理數(shù)據(jù)都是小端傳輸?shù)模?uint16_t 數(shù)據(jù)映射到數(shù)組里就是低8位在前,高8位在后 形如{低8位卿城,高8位 } 的數(shù)組,到這里大家是不是覺得很簡單铅搓。NO NO NO瑟押,too ?? 了。星掰。多望。嫩舟。

莫急,我們可以測試打印的 sizeof (Test_struct)= 8怀偷;

下面比較下面的協(xié)議:

我們?nèi)绻凑丈厦孢壿嬑覀儠@樣構(gòu)建

typedef struct{????uint8_t head; ?uint16_t?data;? ? uint8_t place[2];? ? uint8_t check;? ? uint8_t tail;}Test_struct;

但是如果你打印一下 size 的話家厌,你會發(fā)現(xiàn)sizeof(Test_struct)還是等于 8;明明比上面少一位怎么還是8位椎工?

原因是 根據(jù)結(jié)構(gòu)體原則饭于。第二位成員2個字節(jié),第二位成員內(nèi)存從結(jié)構(gòu)體開始 2字節(jié)的倍數(shù)位開始排维蒙。所以 第一個成員占了第1字節(jié) 還有個補位第二個字節(jié)掰吕,uint16個低8位占了第三個字節(jié),?uint16個高8位占了第四個字節(jié)颅痊。加上后面的4個字節(jié)殖熟,一共8個字節(jié),第三原則(最大成員字節(jié)的整數(shù)陪)總字節(jié)數(shù)8的確是 最大成員2字節(jié)的整數(shù)倍斑响。

那這樣的話我們怎樣構(gòu)建結(jié)構(gòu)體方便些呢菱属?

1 。第一種把所有結(jié)構(gòu)體 改成一個字節(jié) 舰罚,意思是把uint16 高低字節(jié)拆開照皆。(常規(guī)做法)。

2沸停。結(jié)構(gòu)體補位

第一種就不用說了膜毁,我們試下第二種怎么做。

typedef struct{ uint8_t head; uint8_t space; uint16_t data; uint8_t place[2]; uint8_t check; uint8_t tail; }Test_struct;

注意刪除線愤钾。我們在head 后面補了一位瘟滨。補了一位數(shù)據(jù)自然有出入,莫急能颁。我們最后生成的時候把這一位刪除數(shù)據(jù)就對了杂瘸。當(dāng)然方法有很多(數(shù)組遍歷賦值等等),我就用內(nèi)存拷貝補位前和補位后的內(nèi)存這種方法伙菊。

NSData * struct2NSdata(Test_struct *context) {

????????int temp_size = sizeof(Test_struct) - 1; //有效的數(shù)據(jù)字節(jié)數(shù)

????????uint8_t ?*temp_context = (uint8_t *)context; //強轉(zhuǎn)結(jié)構(gòu)體指針類型败玉,為了后面一個字節(jié)的偏移量

????????uint8_t *temp = malloc(temp_size);//分配內(nèi)存

????????memset(temp, 0, temp_size); //內(nèi)存塊初始化0

????????memcpy(temp, temp_context, 1);//拷貝第一位;

????????memcpy(temp + 1,temp_context + 2, temp_size - 1); //拷貝context第3位至結(jié)尾

????????NSData *result = [NSData dataWithBytes:temp length:temp_size]; //最終生成的data

????????free(temp); //釋放開辟的內(nèi)存

????????return result;

}

對于NSData 轉(zhuǎn)結(jié)構(gòu)體也是一個辦法補一位 哈哈

void nsdata2Struct(NSData *data , Test_struct *context) {

????????int temp_size = data.length; //有效的數(shù)據(jù)字節(jié)數(shù)

????????uint8_t *temp_context = context; //強轉(zhuǎn)結(jié)構(gòu)體

????????uint8_t *head_data = malloc(1);

????????[data getBytes:head_data range:NSMakeRange(0, 1)]; //儲存前內(nèi)存塊

? ? ? ? uint8_t *tail_data = malloc(temp_size - 1);

????????[data getBytes:head_data range:NSMakeRange(1, temp_size - 1)]; //儲存后面內(nèi)存塊

????????memcpy(temp_context, head_data, 1); //拷貝前內(nèi)存

????????memcpy(temp_context + 2, tail_data, data.length - 1); //拷貝后面的內(nèi)存塊 到第三字節(jié)至結(jié)尾 (忽略第二位)

????????free(head_data); //釋放

????????free(tail_data);

}

還有結(jié)構(gòu)體 第三原則 必須是最大成員的整數(shù)倍,如果不是會在結(jié)構(gòu)體最后一位補位镜硕。 處理方法也和上面類似运翼。

? 綜上,如果數(shù)據(jù)都是一個字節(jié)數(shù)據(jù)兴枯,構(gòu)建可以什么都不用考慮血淌,

?如果數(shù)據(jù)為小端傳輸,可以用上面方法,考慮一下結(jié)構(gòu)體對齊悠夯,不對齊需要補位癌淮,優(yōu)點是,數(shù)據(jù)轉(zhuǎn)換的時候不需要一個個賦值沦补,反正我是寫的手疼乳蓄。?

如果數(shù)據(jù)為大端傳輸,還是老老實實把成員都變成一個字節(jié)的成員變量夕膀,或者寫個函數(shù)高低位轉(zhuǎn)換虚倒。在用上面所提的方法。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末店诗,一起剝皮案震驚了整個濱河市裹刮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌庞瘸,老刑警劉巖捧弃,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異擦囊,居然都是意外死亡违霞,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門瞬场,熙熙樓的掌柜王于貴愁眉苦臉地迎上來买鸽,“玉大人,你說我怎么就攤上這事贯被⊙畚澹” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵彤灶,是天一觀的道長看幼。 經(jīng)常有香客問我,道長幌陕,這世上最難降的妖魔是什么诵姜? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮搏熄,結(jié)果婚禮上棚唆,老公的妹妹穿的比我還像新娘。我一直安慰自己心例,他們只是感情好宵凌,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著契邀,像睡著了一般摆寄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上坯门,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天微饥,我揣著相機與錄音,去河邊找鬼古戴。 笑死欠橘,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的现恼。 我是一名探鬼主播肃续,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼叉袍!你這毒婦竟也來了始锚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤喳逛,失蹤者是張志新(化名)和其女友劉穎瞧捌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體润文,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡姐呐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了典蝌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片曙砂。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖骏掀,靈堂內(nèi)的尸體忽然破棺而出鸠澈,到底是詐尸還是另有隱情,我是刑警寧澤截驮,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布笑陈,位于F島的核電站,受9級特大地震影響侧纯,放射性物質(zhì)發(fā)生泄漏新锈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一眶熬、第九天 我趴在偏房一處隱蔽的房頂上張望妹笆。 院中可真熱鬧,春花似錦娜氏、人聲如沸拳缠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窟坐。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哲鸳,已是汗流浹背臣疑。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留徙菠,地道東北人讯沈。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像婿奔,于是被迫代替她去往敵國和親缺狠。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容

  • GNU C的一大特色就是__attribute__機制萍摊。__attribute__可以設(shè)置函數(shù)屬性(Functio...
    閉家鎖閱讀 17,276評論 0 5
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉挤茄,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,715評論 0 9
  • 1 Block機制 (Very Good) Block技巧與底層解析 http://www.reibang.com...
    Kevin_Junbaozi閱讀 4,046評論 3 48
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)冰木,斷路器穷劈,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • 先感嘆一句:時間過的真快囚衔,2018年轉(zhuǎn)眼過去2個月了。 剛好結(jié)束財報入門學(xué)習(xí)系列的文章雕沿,以及這段時間發(fā)生了一些事情...
    跡歸云_周照閱讀 205評論 0 0