I'm using Rust to test some C code:
lol.c
#include "lol.h"
int a[10]; //Assume lol.h has an extern declaration for a[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] }
}
I used the cc crate to compile and link lol.o. How do I write the set_a
and get_a
functions? The compiler says:
error[E0608]: cannot index into a value of type `*mut i32`
--> src/main.rs:8:9
|
8 | a[index] = val;
| ^^^^^^^^
error[E0608]: cannot index into a value of type `*mut i32`
--> src/main.rs:14:14
|
14 | unsafe { a[index] }
| ^^^^^^^^
You could use the offset
method to find a single element, or use std::slice::from_raw_parts_mut
to create a slice from pointer and (possibly dynamic) length, or use static mut a: *mut [i32; 10]
in the first place (use (*a)[index]
to use it).
But: I'm pretty sure that int a[10];
from C
doesn't export a location of a pointer to that array, it exports the location of the array (i.e the location of the first element), and extern
in Rust expects a location to a value of the given type (i.e. it is implemented as a pointer on both sides) , so I'd try this:
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] }
}