我有一个DLL,可导出一堆我想在Rust中使用的C函数。我具有以下导出的函数,分别用于创建句柄和删除它的DLL API:
__declspec(dllexport) int create_handle(handle** ptr);
__declspec(dllexport) int close_handle(handle* h);
我尝试以几种不同的方式实现它,例如:
extern crate libc;
use libc::{c_int, c_float, c_void};
#[link(name = "my_dll")]
extern {
fn create_handle(handle: *mut c_int) -> i32;
fn close_handle(handle: i32) -> i32;
}
fn main() {
unsafe {
let mut ptr = 0 as i32;
let ret = create_handle(&mut ptr);
if ret != 0 {
panic!("return code fail: {0}", ret);
}
let ret = close_handle(ptr);
if ret != 0 {
panic!("return code fail: {0}", ret);
}
}
}
尽管ptr
被分配了一个值,但这不是预期的值。 close_handle
本机函数检查传递的指针是否与创建的指针匹配。在此代码中,到达第二个panic!
。
我对Rust还是很陌生,因此目前我对指针的互操作性还不太清楚。本机函数将进行正确的类型转换,因此我应该使用c_void
类型吗?还是具有指针值的i32
就足够了?
答案 0 :(得分:0)
这是可行的解决方案:
extern crate libc;
#[link(name = "my_dll")]
extern {
fn create_handle(handle_ptr: *mut *mut i32) -> i32;
fn close_handle(handle: *mut i32) -> i32;
}
fn main() {
unsafe {
let mut handle: *mut i32 = std::ptr::null_mut();
let handle_ptr: *mut *mut i32 = &mut handle;
let ret = create_handle(handle_ptr);
if ret != 0 {
panic!("return code fail: {0}", ret);
}
let ret = close_handle(handle);
if ret != 0 {
panic!("return code fail: {0}", ret);
}
}
}
解决方案是在How do I make the equivalent of a C double pointer in Rust?上找到*mut *mut
符号来引用std::ptr::null_mut()
。