我有这种生锈方法:
/* Define a python method on a given module */
pub fn method(data: *mut Struct_ppyData, module: ~str, method: ~str, callback: PyCFunction, flags: Method, help: ~str) {
let mbytes = module.to_c_str().with_mut_ref(|a: * mut c_char| { a });
let fbytes = method.to_c_str().with_mut_ref(|b: * mut c_char| { b });
let dbytes = help.to_c_str().with_mut_ref(|c: * mut c_char| { c });
println!("Incoming! {} {} {}\n", module, method, help);
println!("Invoking! {} {} {}\n", mbytes, fbytes, dbytes);
let cflags = flags as c_int;
unsafe {
ppy_method(data, mbytes, fbytes, callback, cflags, dbytes);
}
}
我得到的输出是:
Incoming! yyy xxx A callback.
Invoking! 0x7f85084077d0 0x7f85084077d0 0x7f85084077d0
什么?这也是ffi c调用的内容:
Received a value
Pointer: 7f85084077d0
length: 11
--------> value: A callback.
Received a value
Pointer: 7f85084077d0
length: 11
--------> value: A callback.
Received a value
Pointer: 7f85084077d0
length: 11
--------> value: A callback.
为什么地球上的mbytes,fbytes和dbytes的值都是一样的? O_O
答案 0 :(得分:2)
你正在做的事情是不安全的,它正在绊倒你。
module.to_c_str()
为CString
分配空间。在with_mut_ref
上调用*T
会向*mut T
提供不安全的指针(CString
或*mut c_char
) - 但CString
仅对关闭时有效你传入。你已经让它在关闭结束后保持活力,因此所有的赌注都已关闭;实际上,*T
在表达式之后立即被释放,因为它不存储在任何地方。因此,你有一个悬空的不安全指针(&str
被称为不安全的原因!)。然后,下一行进行类似的分配和lo!它在同一个地方。最终结果:三个相同的指针,都指向相同的垃圾数据。
如果你确实需要这样一个不安全的指针,那么你应该做的就是嵌套东西。
此外,正如dbaupp所观察到的,您不需要取得字符串的所有权;您也可以使用~str
代替/// Define a python method on a given module
pub fn method(data: *mut Struct_ppyData, module: &str, method: &str,
callback: PyCFunction, flags: Method, help: &str) {
module.to_c_str().with_mut_ref(|mbytes| {
method.to_c_str().with_mut_ref(|fbytes| {
help.to_c_str().with_mut_ref(|dbytes| {
println!("Incoming! {} {} {}\n", module, method, help);
println!("Invoking! {} {} {}\n", mbytes, fbytes, dbytes);
let cflags = flags as c_int;
unsafe {
ppy_method(data, mbytes, fbytes, callback, cflags, dbytes);
}
})
})
})
}
。
{{1}}