I have C code to bridge to. I chose to use mem::uninitialized
to claim the memory first, then call the C function(UserInit
) to do initialisation, then use it (in UserDoSomething
).
The odd thing is the addresses of the object are different in UserInit
and UserDoSomething
. Why does it behave in this way?
The C code:
typedef struct {
char* name;
int32_t age;
} User;
void
UserInit(User* u){
printf("in init: user addr: %p\n", u);
}
void
UserDoSomething(User* u){
printf("in do something user addr: %p\n", u);
}
void
UserDestroy(User* u){
free(u->name);
}
The Rust FFI:
use std::mem;
use std::os::raw::c_char;
use std::ffi::CString;
#[repr(C)]
pub struct User{
pub name: *const c_char,
pub age: i32,
}
impl User {
pub fn new()-> User {
let ret: User = unsafe { mem::uninitialized() };
unsafe {
UserInit(&mut ret as *mut User)
}
ret
}
pub fn do_something(&mut self){
unsafe {
UserDoSomething(self as *mut User)
}
}
}
extern "C" {
pub fn UserInit(u:*mut User);
pub fn UserDoSomething(u:*mut User);
pub fn UserDestroy(u:*mut User);
}
Rust tests:
mod ffi;
use ffi::User;
fn main() {
let mut u = User::new();
u.do_something();
}
In theory, it should output the same address but it doesn't:
> cargo run
Running `target/debug/learn`
in init: user addr: 0x7fff5b948b80
in do something user addr: 0x7fff5b948ba0