Rust C库释放生锈的指针

Rust C库释放生锈的指针,rust,ffi,Rust,Ffi,我想对一个需要回调的C库进行Rust绑定,这个回调必须返回一个指向C库的C-stylechar*指针,然后该指针将释放它。 在某种意义上,回调必须向我的库的用户公开(可能使用闭包),并且我希望提供一个尽可能方便的Rust接口(意味着如果可能,接受字符串输出) 但是,C库在尝试释放()一个来自Rust分配的内存的指针时会抱怨,这可能是因为Rust使用jemalloc,而C库使用malloc 因此,目前我可以看到使用libc::malloc()的两种变通方法,但它们都有缺点: 为库的用户提供一个他

我想对一个需要回调的C库进行Rust绑定,这个回调必须返回一个指向C库的C-style
char*
指针,然后该指针将释放它。 在某种意义上,回调必须向我的库的用户公开(可能使用闭包),并且我希望提供一个尽可能方便的Rust接口(意味着如果可能,接受
字符串
输出)

但是,C库在尝试
释放()
一个来自Rust分配的内存的指针时会抱怨,这可能是因为Rust使用jemalloc,而C库使用malloc

因此,目前我可以看到使用
libc::malloc()
的两种变通方法,但它们都有缺点:

  • 为库的用户提供一个他必须填写的切片(不方便,并施加长度限制)
  • 获取他的
    字符串
    输出,将其复制到malloc分配的数组中,然后释放
    字符串
    (无用的复制和分配)
有人能想出更好的解决办法吗

这里是C库接口的等价物,以及理想情况的实现(如果C库可以释放Rust中分配的字符串)

C部分相当于:

#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");