I was wondering if Box
is safe to expose in FFI signatures. Box
is not marked as repr(C)
but its layout seems to be compatible. Consider for example the following C-API:
#ifndef TEST_H
#define TEST_H
#include <stddef.h>
#include <stdint.h>
typedef struct vector_t vector_t;
void new(vector_t **);
void del(vector_t *);
void add(uint8_t, vector_t *);
size_t len(vector_t const *);
#endif
Would this Rust implementation be safe?
use std::ptr;
#[no_mangle]
pub extern fn new(x: *mut Box<Vec<u8>>) {
let v = Box::new(Vec::new());
unsafe {
ptr::write(x, v)
}
}
#[no_mangle]
pub extern fn del(_: Box<Vec<u8>>) {}
#[no_mangle]
pub extern fn add(x: u8, v: &mut Vec<u8>) {
v.push(x)
}
#[no_mangle]
pub extern fn len(v: &Vec<u8>) -> usize {
v.len()
}
It certainly compiles and links fine with a little test program:
#include <assert.h>
#include <test.h>
int main () {
vector_t * v = NULL;
new(&v);
add(1, v);
add(2, v);
assert(2 == len(v));
del(v);
}
Am I relying on some unsafe behaviour here or would this be a correct approach to write a Rust FFI?