LabVIEW 2019调用Rust释放CString时崩溃,求正确实现方案
问题背景
我正在使用LabVIEW 2019 64位与Rust 1.64进行交互测试,一段简单代码导致LabVIEW崩溃。需求是将字符串Hello from Rust从Rust传递给LabVIEW,再回传给Rust完成内存释放。
原Rust代码
use libc::c_char; use std::ffi::CString; #[no_mangle] pub extern "cdecl" fn hello() -> *const c_char { CString::new("Hello from Rust") .expect("failed to create c string") .into_raw() } #[no_mangle] pub extern "cdecl" fn bye(s: *mut c_char) { unsafe {drop(CString::from_raw(s));} }
崩溃现象
LabVIEW可以正常显示字符串,但调用bye(s)函数时会先冻结后崩溃。如果手动禁用bye(s)调用则一切正常,但这会违反Rust的内存管理规范:
alloc::ffi::c_str::CString
pub fn into_raw(self) -> *mut c_char
Consumes the CString and transfers ownership of the string to a C caller.The pointer which this function returns must be returned to Rust and reconstituted using CString::from_raw to be properly deallocated. Specifically, one should not use the standard C free() function to deallocate this string.
Failure to call CString::from_raw will lead to a memory leak.
正确解决方式
核心问题是LabVIEW默认会对传入的字符串指针做内存复制或转换,导致传递给bye函数的不再是Rust返回的原始指针。正确的做法是:
- 在LabVIEW中,将
hello函数返回的指针作为原始无类型指针保存,不要直接转换为LabVIEW字符串类型 - 当需要显示字符串内容时,通过LabVIEW的“字符串指针至字符串”函数,从原始指针读取内容(此操作仅复制内容,不修改原始指针)
- 最后将保存的原始指针直接传递给
bye函数,由Rust完成内存释放
可用的LabVIEW程序框图如下:
内容的提问来源于stack exchange,提问作者nochenon

