Rust C库释放生锈的指针
我想对一个需要回调的C库进行Rust绑定,这个回调必须返回一个指向C库的C-styleRust C库释放生锈的指针,rust,ffi,Rust,Ffi,我想对一个需要回调的C库进行Rust绑定,这个回调必须返回一个指向C库的C-stylechar*指针,然后该指针将释放它。 在某种意义上,回调必须向我的库的用户公开(可能使用闭包),并且我希望提供一个尽可能方便的Rust接口(意味着如果可能,接受字符串输出) 但是,C库在尝试释放()一个来自Rust分配的内存的指针时会抱怨,这可能是因为Rust使用jemalloc,而C库使用malloc 因此,目前我可以看到使用libc::malloc()的两种变通方法,但它们都有缺点: 为库的用户提供一个他
char*
指针,然后该指针将释放它。
在某种意义上,回调必须向我的库的用户公开(可能使用闭包),并且我希望提供一个尽可能方便的Rust接口(意味着如果可能,接受字符串
输出)
但是,C库在尝试释放()
一个来自Rust分配的内存的指针时会抱怨,这可能是因为Rust使用jemalloc,而C库使用malloc
因此,目前我可以看到使用libc::malloc()
的两种变通方法,但它们都有缺点:
- 为库的用户提供一个他必须填写的切片(不方便,并施加长度限制)
- 获取他的
输出,将其复制到malloc分配的数组中,然后释放字符串
(无用的复制和分配)字符串
#include <stdlib.h>
typedef char* (*callback)(void *arbitrary_data);
void need_callback(callback cb, void *arbitrary_data) {
char *user_return = cb(arbitrary_data);
free(user_return); // Complains as the pointer has been allocated with jemalloc
}
#包括
typedef char*(*回调)(void*任意_数据);
void需要回调(回调cb,void*任意数据){
char*user_return=cb(任意_数据);
free(user_return);//由于指针已分配给jemalloc,因此发出抱怨
}
这可能需要您做一些烦人的工作,但是如何公开一个实现了的类型,但是由通过malloc分配的内存支持呢?然后,您的客户可以使用write代码>宏(和朋友),而不是分配字符串
以下是它当前如何与Vec一起工作:
let mut v = Vec::new();
write!(&mut v, "hello, world");
您将“只”需要实现这两个方法,然后您将拥有一个流式接口 哦,我没想到,谢谢!虽然如果我是正确的,malloc有一个相当愚蠢的realloc函数,它只执行malloc/copy/free,而jemalloc可以执行realloc。因此,在malloc中实现的可增长类型可能意味着在重新分配期间有多个副本,这意味着使用经典字符串,然后执行单个malloc/copy,可能更方便、更快。我想我需要做一些测试!或者你以后可以用绳子和马洛克。Crates.io有两条绳子。@ArtemGr绳子不会涉及生锈端的分配,因此以后需要通过malloc进行第二次分配吗?@Vaelden我认为realloc
没有“哑”实现,而且可能很难全局描述realloc
——如果每个平台都有不同的实现,我也不会感到惊讶,而且您可以在运行时使用自定义库替换malloc
和friends。我同意,如果您担心性能问题,那么评测是正确的解决方案@当然可以。不过,这是构建字符串的最有效方法,因为它避免了realloc过程中的复制。这里有一个奇怪的评论--“kmc:SM使用绳索吗?zwarich:每个人都使用。”;)更不用说,这种方式内存效率更高,避免了长时间使用缓冲区末尾的额外内存。
let mut v = Vec::new();
write!(&mut v, "hello, world");