لماذا تشير كل مؤشراتي إلى نفس المكان مع to_c_str() في الصدأ؟
-
22-12-2019 - |
سؤال
لدي طريقة الصدأ هذه:
/* 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.
لماذا بحق السماء تكون قيم الميجابايت و fbytes و dbytes كلها متشابهة؟O_O
المحلول
ما تفعله غير آمن، ويعرقلك.
module.to_c_str()
يخصص مساحة ل CString
.الاتصال with_mut_ref
على ذلك يعطي مؤشر غير آمن (*T
أو *mut T
) إلى ذلك CString
-لكن ذلك *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);
}
})
})
})
}