libuv - 自由写入缓冲区

libuv - free write buffer

本文关键字:缓冲区 自由 libuv      更新时间:2023-10-16

uv_write的文档指出[1]:

注意缓冲区指向的内存必须保持有效,直到调用回调。这也适用于 uv_write2((。

因此,可能需要对缓冲区的基进行动态分配。调用函数可能如下所示:

void write_to_stream(uv_stream_t* stream) {   
uv_write_t* write_req = new uv_write_t;
uv_buf_t buf{};
buf.base = new char[1024];
buf.len = 1024;
// fill the buffer
uv_write(write_req, stream, buf, 1, on_write);
}

在这种情况下,new char[1024]分配的内存需要有效,直到触发on_write回调。

查看回调的签名void on_write(uv_write_t* req, int status)如何释放此内存并不明显,因为似乎无法从回调中访问此指针。

void on_write(uv_write_t* req, int status) {
// how to find the memory allocated for req's buffer?
delete[] ???;
}

不再需要此内存后释放此内存的预期方法是什么?

由于libuv是一个 c 库,因此其结构应该是标准布局类型。因此,您可以将uv_write_tuv_buf_t包装在上下文结构中,然后再转换回上下文结构。请参阅以下示例:

struct write_context_t {
uv_write_t write_req;
uv_buf_t buf;
~write_context_t() {
delete[] buf.base;
}
}
void on_write(uv_write_t* req, int status) {
write_context_t* context = reinterpret_cast<write_context_t*>(req);
/* Do stuff ... */
delete context;
}
void write_to_stream(uv_stream_t* stream) {   
write_context_t* write_req = new write_context_t;
/* fill your write_req and buf info here ... */
// initiate write
uv_write(&write_req.write_req, stream, write_req.buf, 1, on_write);
}

这是因为指向标准布局对象的第一个非静态数据成员的指针可与指向该对象的指针相互转换。

另一种方法是使用data. 请注意,所有 uv 手柄都包含一个data字段,可以根据自己的需要使用它。

void write_to_stream(uv_stream_t* stream) {   
uv_write_t* write_req = new uv_write_t;
write_req.data = new char[1024];
uv_buf_t buf{};
buf.base = write_req.data;
buf.len = 1024;
// fill the buffer
uv_write(write_req, stream, buf, 1, on_write);
}
void on_write(uv_write_t* req, int status) {
delete[] req.data;
delete req;
}