擅长:python、mysql、java
<p>最直接的说法是:</p>
<pre class="lang-rust prettyprint-override"><code>use libc::c_char;
use std::ffi::CString;
use std::mem;
#[no_mangle]
pub extern fn query() -> *mut c_char {
let s = CString::new("Hello!").unwrap();
s.into_raw()
}
</code></pre>
<p>这里我们返回一个指向<code>char</code>s的以零结尾的序列的指针,该序列可以传递给Python的<code>c_char_p</code>。你不能仅仅返回<code>CString</code>,因为它是Rust结构,不应该直接在C代码中使用——它包装了<code>Vec<u8></code>,实际上由三个指针大小的整数组成。它与C的<code>char*</code>不直接兼容。我们需要从中得到一个原始指针。<a href="http://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_raw" rel="nofollow">^{<cd6>}</a>方法就是这样做的——它按值使用<code>CString</code>,“忽略”它,这样它的分配就不会被破坏,并返回一个指向数组开头的<code>*mut c_char</code>指针。在</p>
<p>然而,这样的话,字符串就会被泄露,因为我们忘记了它在锈边的分配,它永远也不会被释放。我不太了解Python的FFI,但是解决这个问题最直接的方法是创建两个函数,一个用于生成数据,另一个用于释放数据。然后需要通过调用以下释放函数从Python端释放数据:</p>
^{pr2}$
<p><a href="http://doc.rust-lang.org/std/ffi/struct.CString.html#method.from_raw" rel="nofollow">^{<cd9>}</a>方法接受一个<code>*mut c_char</code>指针并从中创建一个<code>CString</code>实例,计算进程中底层以零结尾的字符串的长度。此操作意味着所有权转移,因此结果<code>CString</code>值将拥有分配,当它被删除时,分配将被释放。这正是我们想要的。在</p>