rust - 在 Rust 的外部函数中使用指向指针的指针的正确方法是什么?

标签 rust ffi

我有一个 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/

相关文章:

rust - 如何将多个 Rust 文件编译成一个 C 库?

rust - 在堆上分配一个结构或让一个结构拥有一个堆指针更惯用吗?

java - 如何在 jnr ffi 中使用结构体和结构体

rust - 如何处理可以拥有或借用的 FFI 未确定大小的类型?

rust - 无法重新借用变量,因为我不能将不可变的局部变量借用为可变的

rust - Rust 中引用与值的显式注释

python - 如何使用 PyO3 解码 PyCodeObject?

rust - 使结构比赋予该结构的方法的参数更长寿

rust - 如何将 Windows OsString 转换为 CString?

reference - 我如何返回一个引用了 RefCell 中某些内容的迭代器?