【问题标题】:Why are all my pointers pointing to the same place with to_c_str() in rust?为什么我所有的指针都指向与 to_c_str() 在 rust 中的同一个地方?
【发布时间】:2014-04-14 06:32:05
【问题描述】:

我有这个防锈方法:

/* 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

【问题讨论】:

    标签: rust


    【解决方案1】:

    你正在做的事情是不安全的,它会绊倒你。

    module.to_c_str()CString 分配空间。调用 with_mut_ref 会给出一个指向 CString 的不安全指针(*T*mut T)——但 *mut c_char 仅对你传入的闭包有效。你让它在关闭结束后保持活力,所以所有的赌注都被取消了;事实上,CString 在该表达式之后立即被释放,因为它没有存储在任何地方。因此,您有一个悬空的不安全指针(*T 被称为不安全是有原因的!)。然后,下一行进行类似的分配,瞧!它在同一个地方。最终结果:三个相同的指针,都指向同一个垃圾数据。

    如果你确实需要这样一个不安全的指针,你应该做的是嵌套这些东西。

    另外,正如 dbaupp 所观察到的,您不需要拥有字符串的所有权;您不妨使用&str 而不是~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);
                    }
                })
            })
        })
    }
    

    【讨论】:

    • (在这种情况下不需要所有权,所以借用切片&str~str好得多。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    相关资源
    最近更新 更多