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.