1. 数据大小的动态配置
在uMCN中,数据的类型和大小是通过消息中心(McnHub
)的结构体定义来支持的。特别是,通过McnHub
结构体中的 obj_size
字段动态确定数据的大小,而不是固定使用某种数据类型。这使得uMCN能够处理不同类型和大小的数据。
struct mcn_hub {
const char* obj_name; // 主题名
const uint32_t obj_size; // 主题数据大小
void* pdata; // 存储发布的数据
...
};
-
obj_size
: 当一个主题(Topic)在系统中被定义时,obj_size
通过MCN_DEFINE
宏传递给消息中心,用来指定该主题的数据大小。 -
pdata
: 数据的存储通过指针pdata
来实现,它是一个通用指针(void*
),指向发布者提供的数据。因此,无论数据是整数、浮点数、结构体,甚至是自定义的数据类型,uMCN都可以通过pdata
来存储和传递这些数据。
2. 通过内存动态分配支持不同数据类型
在注册主题(Advertise)时,uMCN会为数据分配所需大小的内存,并将其存储在pdata
中。由于 pdata
是一个通用指针,它能够指向任何类型的数据。
fmt_err_t mcn_advertise(McnHub_t hub, int (*echo)(void* parameter)) {
...
pdata = MCN_MALLOC(hub->obj_size); // 根据 obj_size 动态分配内存
...
}
在mcn_advertise
函数中,uMCN会根据不同主题的数据大小,通过 MCN_MALLOC
函数分配适量的内存来保存发布的数据。因此,发布者可以使用不同大小和类型的数据发布到同一消息中心中,而不会引发类型问题。
3. 数据发布时的类型透明性
数据发布的核心函数mcn_publish
通过 memcpy
将数据复制到 pdata
中,这意味着发布者可以发布任何类型的数据,只要数据大小与主题的 obj_size
相匹配即可。
fmt_err_t mcn_publish(McnHub_t hub, const void* data) {
...
memcpy(hub->pdata, data, hub->obj_size); // 将不同类型的数据复制到消息中心
...
}
在此函数中,data
是一个通用指针(const void*
),它可以指向任何类型的数据。发布时,uMCN通过 memcpy
将数据复制到 pdata
中,而不关心数据的实际类型。只要数据的大小(obj_size
)是正确的,uMCN就能处理该数据。
4. 数据订阅时的类型透明性
在订阅者从主题获取数据时,uMCN通过类似的方式确保了数据类型的透明性。订阅者调用 mcn_copy
函数将数据从消息中心复制到订阅者的缓冲区中。
fmt_err_t mcn_copy(McnHub_t hub, McnNode_t node_t, void* buffer) {
...
memcpy(buffer, hub->pdata, hub->obj_size); // 将数据复制到订阅者的缓冲区
...
}
buffer
: 是一个通用指针,订阅者在订阅时需要为接收到的数据提供足够的内存。mcn_copy
函数将数据从消息中心复制到订阅者的缓冲区中,而不关心数据的具体类型。
5. 主题的声明与定义
uMCN使用 MCN_DECLARE
和 MCN_DEFINE
宏来定义主题。在定义主题时,开发者可以指定该主题的对象大小,即数据类型的大小。
MCN_DEFINE(topic_name, sizeof(data_type));
例如:
- 如果数据类型是一个
int
类型,定义如下:
MCN_DEFINE(topic_int, sizeof(int));
- 如果数据类型是一个
struct
,定义如下:
typedef struct {
int id;
float value;
} my_data_t;
MCN_DEFINE(topic_struct, sizeof(my_data_t));
6. 灵活的回调机制
uMCN支持订阅者通过回调函数来处理接收到的不同类型的数据。每个订阅者在订阅主题时,可以指定一个回调函数,这个回调函数会在数据更新时被调用。
McnNode_t mcn_subscribe(McnHub_t hub, void (*pub_cb)(void* parameter)) {
...
node->pub_cb = pub_cb; // 注册回调函数
...
}
回调函数的参数 parameter
是一个通用指针,因此可以传递任何类型的数据,订阅者可以根据具体的主题进行类型转换和处理。
总结
uMCN通过以下方式支持不同的数据类型:
-
动态确定数据大小:通过
obj_size
字段和void*
通用指针支持不同的数据类型。 - 内存动态分配:根据数据大小动态分配内存,确保系统能够处理多种类型的数据。
-
类型透明性:使用
memcpy
和通用指针,确保数据发布和订阅过程中数据类型的透明性。 - 灵活的主题定义:开发者可以根据需要定义不同大小的数据主题,系统可以处理结构体、基本数据类型等多种数据类型。
这种设计使得uMCN非常灵活,可以广泛应用于嵌入式系统中,处理各种类型的传感器数据、控制信息等。