【发布时间】:2019-07-31 06:39:00
【问题描述】:
我想构建一个环形缓冲区 API,但不是在 API 本身中使用 malloc() 动态创建缓冲区,我想传递已经存在的变量类型数组(uint8_t、uint16_t 等)。
所以我认为实现这一点的最佳方法是声明一个包含所有必需信息和所需 API 函数的结构
typedef struct ring_buffer {
void * buffer;
uint8_t element_size;
size_t head;
size_t tail;
size_t max;
bool full;
} ring_buffer_t;
ring_buffer_t buf_init(void * buffer, uint8_t element_size, size_t max);
void buf_add(ring_buffer_t * handle, uint8_t element);
bool buf_is_emtpy(ring_buffer_t * handle);
void* buf_pop(ring_buffer_t * handle);
ring_buffer_t buf_init(void * buffer, uint8_t element_size, size_t max){
return (ring_buffer_t){.buffer = buffer, .element_size = 2, .head=0, .tail=0, .max=64, .full=false};
}
void buf_add(ring_buffer_t * handle, const uint8_t element){
if(handle->head == handle->max){
handle->head = 0;
}
printf("adding %d at position %d\n", element, (uint8_t)handle->head);
handle->buffer[handle->head] = element;
handle->head += handle->element_size;
}
void* buf_pop(ring_buffer_t * handle){
void* ret;
if(handle->tail < handle->head-1){
printf("Tail is at position %d\n", (uint8_t)handle->tail);
ret = &handle->buffer[handle->tail];
handle->tail += handle->element_size;
} else {
printf("Tail is at position %d\n", (uint8_t)handle->tail);
ret = &handle->buffer[handle->tail];
}
return ret;
}
bool buf_is_emtpy(ring_buffer_t * handle){
if(handle->head == handle->tail){
return true;
} else {
return false;
}
}
但这不起作用,因为 void* 似乎不是处理这个问题的正确方法。如何处理在创建结构时知道大小的指针?因为在 buf_add() 中,我需要将 handle->buffer 转换为正确的指针类型才能添加 element。
解决此类问题的正确方法是什么?
根据给定的答案,我改变了行
handle->buffer[handle->head] = element;
到
memcpy(&handle->buffer[handle->head], element, handle->element_size);
到目前为止,什么有效,但仍然给我一个警告,我是 dereferencing 'void *' pointer 这当然是正确的,但在这种情况下正确的取消引用会是什么样子?
【问题讨论】: