[英]Rust, FFI, and lifetime for string transmutation
I'm working in an FFI library and have encountered this pattern quite a few times that I don't know how to handle idiomatically. 我在FFI库中工作,并且已经多次遇到这种模式,我不知道该如何惯用。
impl CanVoidStar for str {
fn as_cvoid_ptr(&self) -> *const c_void {
let string = CString::new(self).unwrap();
unsafe {
return mem::transmute(string.as_ptr());
}
}
}
My intent was to create a const *void
pointer to a piece of memory that I can hand off to a C function. 我的意图是创建一个指向内存的
const *void
指针,我可以将其交给C函数。 The problem that here is that string
goes out of scope and thus I get undefined behavior in the unsafe
block. 这里的问题是
string
超出范围,因此我在unsafe
块中得到未定义的行为。
Is there a way I can keep string
allocated on the heap until whatever it is that is using the return value done with it? 有什么办法可以让
string
在堆上保持分配状态,直到使用返回值完成它是什么为止? Further, is there a idiomatic way to handle this or do I need to redesign my algorithms? 此外,是否有惯用的方式来处理此问题,还是需要重新设计算法?
It looks like you're using the wrong method on CString
, and CString::into_raw()
is what you want. 似乎您在
CString
上使用了错误的方法,而CString::into_raw()
是您想要的。 Even better, it needs no unsafe
code until you want to free the memory again. 更好的是,它不需要
unsafe
代码,直到您想再次释放内存。
While CString::as_ptr()
returns a pointer into the string, CString::into_raw()
passes the ownership of the memory into the raw pointer; CString::as_ptr()
将指针返回到字符串中,而CString::into_raw()
将内存的所有权传递到原始指针中。 this is intended for exactly your use case: 这完全适合您的用例:
trait CanVoidStar {
fn as_cvoid_ptr(&self) -> *const c_void;
}
impl CanVoidStar for str {
fn as_cvoid_ptr(&self) -> *const c_void {
let string = CString::new(self).unwrap();
string.into_raw() as *const c_void
}
}
As the documentation says, if you ever want to free it, you'll need to reconstruct the CString
using CString::from_raw()
and then have it dropped as usual. 如文档所述,如果要释放它,则需要使用
CString::from_raw()
重建CString
,然后照常删除它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.