简体   繁体   English

字符串转换的Rust,FFI和生存期

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM