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

问题描述 投票:-1回答:1

我有一个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足够?

rust ffi
1个回答
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);
        }
    }
}

解决方案是*mut *mut表示法,引用了在std::ptr::null_mut()上找到的How do I make the equivalent of a C double pointer in Rust?

© www.soinside.com 2019 - 2024. All rights reserved.