我有一个 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
native 函数检查传递的指针是否与创建的指针匹配。在这段代码中,出现了第二个 panic!
。
我是 Rust 的新手,所以指针互操作性目前对我来说不是很清楚。 native 函数将执行正确的类型转换,所以我应该使用 c_void
类型吗?还是具有指针值的 i32
就足够了?
最佳答案
这是有效的解决方案:
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);
}
}
}
解决方案是使用 *mut *mut
符号来引用 std::ptr::null_mut()
,在 How do I make the equivalent of a C double pointer in Rust? 上找到.
关于rust - 在 Rust 的外部函数中使用指向指针的指针的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58530104/