I’m trying to wrap a C-api into Rust. It’s an astronomy data format library cfitsio.
Encapsulating the file state is a
fitsfile struct, which is managed by the open and close functions:
fitsfile *fptr; // struct holding file position etc. int status = 0; // how errors are reported // Open a file on disk fits_open_file(&fptr, "filename.fits", READONLY, &status); // Close the file fits_close_file(fptr, &status);
fits_open_file function allocates the memory, and sets the given pointer to the allocated memory. I have started to wrap this pointer object, but want to use Rust’s borrowing semantics to manage mutability of this state object, hopefully allowing concurrent file access (which is not supported in the C-api).
My WIP wrapper library wraps this
fitsfile into a rustier
FitsFile (source) object, and stores a
*const fitsfile member. It’s
const because the pointer itself does not change. My issue is that the memory it points to does change.
Currently using the
FitsFile object does not require it to be defined as
mut which is mis-representing how the library works.
What I’d like to do is store the
fitsfile object itself. It’s not defined as
Copy so move semantics should be in play, but Rust does not allow moving from dereferenced raw pointers.
One reasonable alternative is to ensure that any methods added to this struct (or other relevant state structs) accept
&mut self. Is this typically done in ffi code?
Yet another alternative is to design an API that does not reflect the C api, but is more typical of Rust APIs, but this needs more thought. I partly feel that the end user should not need to worry about the in-memory representation of the file state changing, but only when the user wants to change the file. I may consider a further high level API wrapping the current one which is more user-friendly.
This is my first serious Rust project, and I’d be interested to hear any comments.