通过Rust FFI更改C数组元素
我正在使用Rust测试一些C代码: lol.c通过Rust FFI更改C数组元素,rust,ffi,Rust,Ffi,我正在使用Rust测试一些C代码: lol.c #包括“lol.h” INTA[10]//假设lol.h有[10]的外部声明 lib.rs extern "C" { static a: *mut i32; } fn set_a(val: i32, index: usize) { assert!(index < 10); unsafe { a[index] = val; } } fn get_a(index: usize) { a
#包括“lol.h”
INTA[10]//假设lol.h有[10]的外部声明
lib.rs
extern "C" {
static a: *mut i32;
}
fn set_a(val: i32, index: usize) {
assert!(index < 10);
unsafe {
a[index] = val;
}
}
fn get_a(index: usize) {
assert!(index < 10);
unsafe { a[index] }
}
使用:
像这样:
extern crate libc;
use libc::malloc;
use std::mem::size_of;
unsafe fn zero(data: *mut u32, length: usize) {
for i in 0..length - 1 {
let ptr = data.offset(i as isize) as *mut u32;
*ptr = 0;
}
}
unsafe fn set(data: *mut u32, offset: usize, value: u32) {
let ptr = data.offset(offset as isize) as *mut u32;
*ptr = value;
}
unsafe fn get(data: *mut u32, offset: usize) -> u32 {
let ptr = data.offset(offset as isize) as *mut u32;
return *ptr;
}
unsafe fn alloc(length: usize) -> *mut u32 {
let raw = malloc(length * size_of::<*mut u32>());
return raw as *mut u32;
}
fn main() {
unsafe {
let data = alloc(10);
zero(data, 10);
println!("{:?}", get(data, 4));
set(data, 4, 100);
println!("{:?}", get(data, 4));
}
}
extern板条箱libc;
使用libc::malloc;
使用std::mem::size\u;
不安全fn零(数据:*mut u32,长度:usize){
对于0..length-1中的i{
设ptr=data.offset(i为isize)为*mut u32;
*ptr=0;
}
}
不安全fn集合(数据:*mut u32,偏移量:usize,值:u32){
设ptr=data.offset(偏移量为isize)为*mut u32;
*ptr=值;
}
不安全的fn get(数据:*mut u32,偏移量:usize)->u32{
设ptr=data.offset(偏移量为isize)为*mut u32;
返回*ptr;
}
不安全fn alloc(长度:usize)->*mut u32{
设raw=malloc(长度*大小::());
返回原始值为*mut u32;
}
fn main(){
不安全{
设数据=alloc(10);
零(数据,10);
println!(“{:?}”,get(data,4));
集合(数据,4100);
println!(“{:?}”,get(data,4));
}
}
您可以使用该方法查找单个元素,或者使用从指针和(可能是动态的)长度创建切片,或者首先使用静态mut a:*mut[i32;10]
(使用(*a)[index]
使用它)
但是:我很确定inta[10]
fromC
不会导出指向该数组的指针的位置,它会导出数组的位置(即第一个元素的位置),而extern
在Rust中会将位置导出为给定类型的值(即,它在两侧都实现为指针),因此我会尝试以下方法:
extern "C" {
static mut a: [i32; 10];
}
fn set_a(val: i32, index: usize) {
unsafe {
a[index] = val;
}
}
fn get_a(index: usize) -> i32 {
unsafe { a[index] }
}
旁白:C的锈当量
int
不是i32
;它在板条箱里。这正是我想要的。工作得很好我有两个问题?使用isize是因为C索引不同于Rust吗?还有你为什么要去马洛克。空间已经在C中分配了,对吗?@KDN malloc只是一个例子(上面的代码在play.rust-lang.org上运行)。显然,在你的情况下,没有必要这样做。usize是因为在C语言中使用x[-1]是合法的(有时也是有意义的);所以offset()可以取-ve数字。在本例中,允许-ve值是没有意义的,因此我将其设为usize而不是isize,但这是任意的。如果你不在乎,就用isize。
extern "C" {
static mut a: [i32; 10];
}
fn set_a(val: i32, index: usize) {
unsafe {
a[index] = val;
}
}
fn get_a(index: usize) -> i32 {
unsafe { a[index] }
}