在Rust中,在外部函数中使用指向指针的指针的正确方法是什么?
我有一个DLL,它导出了一堆我想在Rust中使用的C函数。我有以下导出函数,分别用于为DLL API创建句柄和删除句柄:在Rust中,在外部函数中使用指向指针的指针的正确方法是什么?,rust,ffi,Rust,Ffi,我有一个DLL,它导出了一堆我想在Rust中使用的C函数。我有以下导出函数,分别用于为DLL API创建句柄和删除句柄: \u declspec(dllexport)int创建句柄(句柄**ptr); __declspec(dllexport)int close_handle(handle*h); 我尝试了几种不同的方式来实现它,例如: extern crate libc; use libc::{c_int, c_float, c_void}; #[link(name = "my_dll"
\u declspec(dllexport)int创建句柄(句柄**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\u handle
本机函数检查传递的指针是否与创建的指针匹配。在这段代码中,第二个panic代码>已到达
我是个新手,所以指针的互操作性目前对我来说不是很清楚。本机函数将执行正确的类型转换,因此我应该使用c\u 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()
。很难回答您的问题,因为它不包含。我们无法确定代码中存在的类型(句柄
)或函数(创建句柄
/关闭句柄
)是什么。您的函数声明为(句柄**ptr)
,但与之等价的函数是(句柄:.mut c_int)
。你为什么认为这些是等价的类型?你的问题可以用的答案来回答。如果没有,请回答您的问题以解释差异。否则,我们可以将此问题标记为已回答。@Shepmaster修复了图像导入(它是更大程序的一部分,我复制错误)。感谢您提供有关修订历史记录的信息。我不知道如何在没有DLL的情况下包含最小的可复制示例。我将检查提供的链接并进行后续操作。最小化的DLL代码可能会归结为每个函数一到两条语句,再加上handle
的定义,总共可能有10行。这很容易包括在内,也是创建一个。