C語言擴(kuò)展庫+結(jié)構(gòu)體序列化
掃描二維碼
隨時隨地手機(jī)看文章
前言
編程多年,想必或多或少的都會有自己的擴(kuò)展庫或功能庫,以便快速開發(fā)功能。
使用多年的擴(kuò)展庫或功能庫經(jīng)過了長時間的驗證,或者隨著開發(fā)時間和接觸面不斷地增長,原有的實現(xiàn)方式不滿足現(xiàn)有的需求或者有更好的實現(xiàn)方式,都會進(jìn)行迭代升級。
下面介紹一個個人最近根據(jù)C++標(biāo)準(zhǔn)庫風(fēng)格重新實現(xiàn)了一套容器擴(kuò)展通用庫實現(xiàn),包含鏈表、隊列(FIFO)和棧(LIFO)等,其中包含了結(jié)構(gòu)體定義序列化/反序列化功能。
初步簡單進(jìn)行過驗證而已
介紹
具體功能有:
-
支持多種容器實現(xiàn),包括通用隊列(包括不定長隊列)、棧和鏈表功能
-
支持定義序列化/反序列化的結(jié)構(gòu)體功能
使用到了Boost庫中的PP庫功能宏語法;確保兩邊都需要保持頭文件結(jié)構(gòu)體定義一致
支持基本變量和字符串變量,同時基本變量還支持一維數(shù)組的定義
序列化后的數(shù)據(jù)不需要考慮大小端的問題,同時會對數(shù)據(jù)進(jìn)行編碼壓縮 -
移植了部分 C++ Boost庫中的PP庫功能
可以通過宏語法實現(xiàn)復(fù)雜的宏語言,靈活進(jìn)行使用宏替換規(guī)則,在編譯的時候生成自己期望的代碼
代碼示例
鏈表代碼示例
void test_list(void) { cotList_t listTable; cotList_Init(&listTable); cotList_PushBack(&listTable, "123", strlen("123") + 1);//鏈表尾部添加元素 cotList_PushBack(&listTable, "1234", strlen("1234") + 1); cotList_PushFront(&listTable, "12345", strlen("12345") + 1);//鏈表頭部添加元素 cotList_PushFront(&listTable, "123456", strlen("123456") + 1); cotList_PushFront(&listTable, "1234567", strlen("1234567") + 1); printf("list empty: %d, size: %d\n", cotList_Empty(&listTable), cotList_Size(&listTable)); // 迭代器遍歷鏈表的所有元素 for_list_each(item, listTable) { printf(" item: [%d] %s\n", item->length, (char *)item->pData); } printf("front item: [%d] %s\n", cotList_Front(&listTable)->length, (char *)cotList_Front(&listTable)->pData); printf("back item: [%d] %s\n", cotList_Back(&listTable)->length, (char *)cotList_Back(&listTable)->pData); }
隊列代碼示例
void queue_list(void) { cotQueue_t queue; uint8_t buf[200]; // 創(chuàng)建隊列 cotQueue_Init(&queue, buf, 200, sizeof(int)); int test; test = 15; cotQueue_Push(&queue, &test, sizeof(int)); test = 100; cotQueue_Push(&queue, &test, sizeof(int)); /* 彈出所有元素 */ while (!cotQueue_Empty(&queue)) { int val = COT_Queue_Front(queue, int);// *(int *)cotQueue_Front(&queue); cotQueue_Pop(&queue); printf(" size[%ld] val = %d\n", cotQueue_Size(&queue), val); } }
定義結(jié)構(gòu)體,實現(xiàn)序列化/反序列化
采用宏定義的方式實現(xiàn)
#include "serialize/serialize.h" COT_DEFINE_STRUCT_TYPE(test_t, ((UINT16_T) (val1) (2)) ((INT32_T) (val2) (1)) ((UINT8_T) (val3) (1)) ((INT16_T) (val4) (1)) ((DOUBLE_T) (val5) (1)) ((INT16_T) (val6) (1)) ((STRING_T) (szName) (100)) ((DOUBLE_T) (val7) (1)) ((FLOAT_T) (val8) (1)) ((STRING_T) (szName1) (100)) ) int main() { uint8_t buf[100]; // 定義變量并完成初始化動作 COT_DEFINE_STRUCT_VARIABLE(test_t, test); test.val1[0] = 5; test.val1[1] = 89; test.val2 = -9; test.val3 = 60; test.val4 = -999; test.val5 = 5.6; test.val6 = 200; test.val7 = -990.35145; test.val8 = -80.699; sprintf(test.szName, "test56sgdgdfgdfgdf"); sprintf(test.szName1, "sdfsdf"); // 將結(jié)構(gòu)體的值進(jìn)行序列化數(shù)據(jù) int length = test.Serialize(buf, &test); printf("Serialize: \n"); for (int i = 0; i < length; i++) { printf("%02x %s", buf[i], (i + 1) % 16 == 0 ? "\n" : ""); } printf("\n"); // 先定義變量,再完成初始化動作 test_t test2; COT_INIT_STRUCT_VARIABLE(test_t, test2); // 將序列化的數(shù)據(jù)轉(zhuǎn)為結(jié)構(gòu)體的值 test2.Parse(&test2, buf); printf("val = %d\n", test2.val1[0]); printf("val = %d\n", test2.val1[1]); printf("val = %d\n", test2.val2); printf("val = %d\n", test2.val3); printf("val = %d\n", test2.val4); printf("val = %lf\n", test2.val5); printf("val = %d\n", test2.val6); printf("name = %s\n", test2.szName); printf("val = %lf\n", test2.val7); printf("val = %f\n", test2.val8); printf("name = %s\n", test2.szName1); return 0; }
輸出結(jié)果:
Serialize: 05 59 11 3c cd 0f 40 16 66 66 66 66 66 66 90 03 74 65 73 74 35 36 73 67 64 67 64 66 67 64 66 67 64 66 00 c0 8e f2 cf c5 04 81 6f c2 a1 65 e3 73 64 66 73 64 66 00 val = 5 val = 89 val = -9 val = 60 val = -999 val = 5.600000 val = 200 name = test56sgdgdfgdfgdf val = -990.351450 val = -80.698997 name = sdfsdf
下載鏈接
下載鏈接(點擊閱讀原文):https://gitee.com/const-zpc/cot





