Hi!
I writing a crates that is linked to an external C library. To pass calls to that library I use FFI.
The API of the C lib is straightforward: one function that return a C struct, composed by an int32 and a char * :
typedef struct s_nl_data {
char *essid;
int32_t signal;
} t_nl_data;
/* API */
t_nl_data *get_data();
And this is my Rust code:
use std::ffi::CStr;
use std::os::raw::{c_char, c_int};
#[derive(Debug)]
#[repr(C)]
pub struct LnData {
signal: c_int,
essid: *const c_char,
}
#[derive(Debug)]
pub struct SafeData {
signal: i32,
essid: String,
}
#[link(name = "nl_data", kind = "static")]
extern "C" {
pub fn get_data() -> *const LnData;
}
pub fn data() -> SafeData {
unsafe {
let nl_data = get_data();
SafeData {
signal: (*nl_data).signal,
essid: CStr::from_ptr((*nl_data).essid)
.to_string_lossy()
.into_owned(),
}
}
}
I'm struggle to convert that C struct in a Rust safe struct using the corresponding types.
The signal
is normally a value between -1 and 100.
But when I print/debug the value of the struct I receive I receive:
LnData {
signal: -690688272, // the value is just wrong
essid: 0x0000000000000047,
}
followed by a SIGSEGV..
I don't understand what I'm doing wrong.
Not that I tested the library with a dummy C binary and it works well. (Even valgrind clean)