rust 调用 c语言编译成的 dylib 文件,假设文件名为 libfoo.dylib
(或者 libfoo.so
)
toml 文件添加这个
[lib]
name= "learn_rust"
crate-type = ["cdylib"]
Rust:
// 假设 文件名为 libfoo.dylib
#[link(name = "foo")]
extern "C" {
fn add(a: i32, b: i32) -> i32;
}
fn main() {
let result = unsafe { add(1, 2) };
println!("1 + 2 = {}", result);
}
rust 调用c的时候,c返回的是结构体
// 1. 定义一个结构体,确保与 C 中的结构体具有相同的内存布局
#[repr(C)]
struct MyStruct {
a: i32,
c: i32,
}
// 2. 同上的使用方法
#[link(name = "foo")]
extern "C" {
fn my_func(a: i32, b: i32) -> MyStruct;
}
fn main() {
// 使用结构体
let obj = unsafe { my_func(1, 9) };
println!("{},{}", obj.a, obj.c);
}
rust调用c的时候,返回的是一个指向结构体的指针
#[link(name = "foo")]
#[repr(C)]
struct MyStruct {
a: i32,
b: *mut i32,
}
extern "C" {
fn c_function() -> *mut MyStruct;
}
fn main() {
let result = unsafe { c_function() };
// 要访问结构体中的字段,需要用 std::ptr::read 来读取指针指向的值
let value = unsafe { std::ptr::read((*result).b) };
println!("a = {}, b = {}", (*result).a, value);
}
rust 调用c的时候,传入 char *
类型的字符串,
#[link(name = "foo")]
extern "C" {
fn my_c_function(arg: *const c_char) -> c_int;
}
let arg = CString::new("hello").unwrap().as_ptr();
let result = unsafe { my_c_function(arg) };
rust 调用 c 的时候,入参是 char **
(指向字符串)
#[link(name = "foo")]
extern "C" {
fn c_function(arg: *mut *mut c_char);
}
let my_string = "Hello, world!";
let c_string = CString::new(my_string).unwrap();
let c_string_ptr = c_string.as_ptr() as *mut c_char;
unsafe {
c_function(&mut c_string_ptr);
}
rust 调用 c 的时候,入参是 char **
(指向一个字符串数组)
use std::ffi::CString;
use std::os::raw::{c_char, c_int};
#[link(name = "foo")]
extern "C" {
fn my_func(len_s: c_int, strings: *mut *mut c_char);
}
fn main() {
let strings = vec!["hello", "world!"];
let c_strings: Vec<_> = strings
.iter()
.map(|s| CString::new(*s).unwrap().into_raw())
.collect();
let mut c_string_ptrs: Vec<_> = c_strings.iter().map(|s| *s as *mut c_char).collect();
let res = unsafe { my_func(c_string_ptrs.len() as i32, c_string_ptrs.as_mut_ptr()) };
}
rust 调用c,其中c返回一个int类型的数组,如何写代码
use libc::{c_int, size_t};
use std::slice;
extern "C" {
fn my_c_function() -> *const c_int;
}
fn main() {
unsafe {
let ptr = my_c_function();
let len = 10; // 假设数组长度为 10
let slice = slice::from_raw_parts(ptr, len as usize);
for i in 0..len {
println!("array[{}] = {}", i, slice[i as usize]);
}
}
}