rust - 如何使用 Rust 的 FFI 从 C 中获取输出字符串参数?
问题描述
我一直在用 Rust 深入研究 FFI,虽然有一些有用的帖子和文档关于传入字符串,有时还会从 C 函数中获取字符串作为返回值,但我看不到任何获取 out 参数的方法. 为了让我的脚湿透,我试图访问一个 C 库,该库公开了一个声明为的函数:
unsigned char *some_func(
const unsigned char *key,
unsigned int klen,
const unsigned char *src,
unsigned char *dest,
unsigned int slen);
我认为它应该大致声明为:
use libc;
extern "C" {
fn some_func(
key: *const libc::c_uchar,
klen: libc::c_uint,
src: *const libc::c_uchar,
dest: *mut libc::c_uchar,
slen: libc::c_uint) -> *mut libc::c_uchar;
}
// wrapper
pub fn wrapped_func(key: &str, src: &str) -> String {
unsafe {
let key_len = key.len() as u32;
let key = std::ffi::CString::new(key).unwrap();
let src_len = src.len() as u32;
let src = std::ffi::CString::new(src).unwrap();
let key_ptr = key.as_ptr();
let src_ptr = src.as_ptr();
let mut dest: *mut std::ffi::CStr;
let result = PC1(key_ptr, key_len, src_ptr, &mut dest, src_len);
// ^^^^^^^^^ expected `u8`, found *-ptr
key_ptr = ptr::null();
src_ptr = ptr::null();
let result_string = if let Ok(s) = result.to_str() {
String::from(s)
} else {
String::new()
};
dest = ptr::null();
result_string
}
我有几个问题:
- 我不知道如何正确声明
dest
为我的输出字符串。获取输出字符串的正确方法是什么?从Wrapping Unsafe C Libraries in Rust看来,我需要将其视为CStr
:
对于
const char *
从 C 函数中获取 a 并希望将其转换为 Rust 可以使用的东西的情况,您需要确保它不为空,然后将其转换为&CStr
具有适当生命周期的 a。如果你不知道如何表达一个合适的生命周期,最安全的做法是立即将其转换为拥有String
!
C 代码 - 因此我的 extern 函数 - 将字符串声明为
unsigned char *
,但是当我尝试调用时,我在u8
和之间存在类型不匹配i8
。只是切换extern
to是可以接受的c_char
,还是这很危险?是否设置
key_ptr = ptr::null()
了正确的方式(以及所有需要的方式)来安全地释放内存?
解决方案
推荐阅读
- oracle - regexp_like 性能不佳
- node.js - 在 req.getValidationResult() 方法之后,EJS 页面未呈现/重定向
- c++ - 二叉树运行时误差的后序迭代遍历
- php - 创建新数据时无法保存计算数据
- php - 如何“跟踪”哪些表与我的多表、多词搜索查询匹配?
- matlab - MATLAB:识别最大值和最小值并相应地拆分数据
- python - Python statsmodels:回归摘要,如何获取参考虚拟变量的 p 值?
- python - Python-如何绘制非数值时间序列
- react-native - 如何检查 fetch POST 中的主体是否已发送到反应原生的 API?
- php - 将变体价格添加到 Woocommerce 中的可变产品下拉项目名称