Given an array of structs in Rust consisting of POD types, how do I write it to a disk file that can then be fread()
in C code?
This would need to take into account any padding and packing necessary to allow fread()
to succeed.
Given an array of structs in Rust consisting of POD types, how do I write it to a disk file that can then be fread()
in C code?
This would need to take into account any padding and packing necessary to allow fread()
to succeed.
&[u8]
using unsafe code.&[u8]
to a file.use std::{fs, mem, slice};
#[repr(C)]
struct Datum {
age: u8,
height: i32,
}
fn main() {
let data = [
Datum { age: 0, height: 0 },
Datum { age: 42, height: 99 },
];
let p = data.as_ptr().cast();
let l = data.len() * mem::size_of::<Datum>();
// I copied this code from Stack Overflow and forgot to
// document why it's actually safe and I probably shouldn't
// use this code until I explain it.
let d = unsafe { slice::from_raw_parts(p, l) };
fs::write("data.bin", d).unwrap();
}
main.c
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
const size_t ARRAY_LEN = 2;
struct Datum {
uint8_t age;
int32_t height;
};
int main() {
FILE *file = fopen("data.bin", "rb");
if (!file) {
perror("Unable to open file");
return EXIT_FAILURE;
}
struct Datum data[ARRAY_LEN];
size_t count = fread(&data, sizeof(struct Datum), ARRAY_LEN, file);
if (count != ARRAY_LEN) {
fprintf(stderr, "Could not read the entire array\n");
return EXIT_FAILURE;
}
for (int i = 0; i < ARRAY_LEN; i++) {
struct Datum *datum = data + i;
fprintf(stderr, "age: %d\n", datum->age);
fprintf(stderr, "height: %d\n", datum->height);
}
if (0 != fclose(file)) {
perror("Unable to close file");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
$ cargo run -q
$ cc -Wall -pedantic main.c -o main && ./main
age: 0
height: 0
age: 42
height: 99
See also:
consisting of POD types
This term has no well-defined meaning in Rust. You will want to search for alternative terms.