I’m playing with some FFI with C++. Basically, I want to put some rust in an existing application. I own both sides, so I can provide C-like APIs from either side. I also call functions both ways.
Now, let’s say I create an object of some kind in one language and want to store it in the other for a while, as an opaque pointer (to create a wrapper on the other side, or pass it back in a callback or something).
I have something that works, but I have a feeling there just must be a better way.
When I have a C++ object, I can represent the pointer to it as a pointer to an empty enum, as the book recommends (https://doc.rust-lang.org/book/first-edition/ffi.html#representing-opaque-structs). But this feels a bit fishy and I’ve heard somewhere this isn’t exactly correct. Because, such type doesn’t have any valid representation. Because it can’t exist, there’s no valid address it could exist in, and therefore any pointer to it is invalid. Or are pointers allowed to point to invalid data? Isn’t that undefined behaviour?
Now, the other direction. I have something in Rust (let’s say a struct). That thing isn’t
#[repr(C)] (because it contains other things that are not and these are from other crate). But If I declare an extern C function that takes pointer to that, I get a lint: „found struct without foreign-function-safe representation annotation in foreign module, consider adding a
#[repr(C)] attribute to the type“. Adding the attribute doesn’t help. How severe is the warning? Does that only mean C doesn’t know the correct layout of the struct at the end of the pointer, or does it mean that even the pointer could be „incompatible“ with C (eg. different size, or something)? Am I ok just placing
#[allow(improper_ctypes)] before the function declaration if I never dereference the pointer on the other side, just store it and pass it back later on, or do I have to cast it and pass it as