C语言扩展库+结构体序列化
扫描二维码
随时随地手机看文章
前言
编程多年,想必或多或少的都会有自己的扩展库或功能库,以便快速开发功能。
使用多年的扩展库或功能库经过了长时间的验证,或者随着开发时间和接触面不断地增长,原有的实现方式不满足现有的需求或者有更好的实现方式,都会进行迭代升级。
下面介绍一个个人最近根据C++标准库风格重新实现了一套容器扩展通用库实现,包含链表、队列(FIFO)和栈(LIFO)等,其中包含了结构体定义序列化/反序列化功能。
初步简单进行过验证而已
介绍
具体功能有:
-
支持多种容器实现,包括通用队列(包括不定长队列)、栈和链表功能
-
支持定义序列化/反序列化的结构体功能
使用到了Boost库中的PP库功能宏语法;确保两边都需要保持头文件结构体定义一致
支持基本变量和字符串变量,同时基本变量还支持一维数组的定义
序列化后的数据不需要考虑大小端的问题,同时会对数据进行编码压缩 -
移植了部分 C++ Boost库中的PP库功能
可以通过宏语法实现复杂的宏语言,灵活进行使用宏替换规则,在编译的时候生成自己期望的代码
代码示例
链表代码示例
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]; // 创建队列 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); } }
定义结构体,实现序列化/反序列化
采用宏定义的方式实现
#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"); // 将结构体的值进行序列化数据 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); // 将序列化的数据转为结构体的值 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; }
输出结果:
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





