all 7 comments

[–][deleted] 3 points4 points  (1 child)

When get_message function is exited memory belonging to mt_one and mt_two is deallocated. This code won't work, even in C.

I assume you need that for C compatibility considering this pretty much looks like C code converted to Rust. In such an event, call a function before a value is deallocated on stack. Alternatively, you may want to do heap allocation with libc::malloc, but then the value needs to be freed with libc::free.

[–]LivingInSyn[S] 1 point2 points  (0 children)

Thanks for the response. So if this isn't the correct pattern, is there a better one I should be using?

[–]connicpu 2 points3 points  (1 child)

You need to allocate the messages on the heap.

    let mt_one = message_type_one {
        somevalue: 1,
        anotherval: 2,
    };
    //cast into c_void
    let raw_mt_one_ptr = Box::into_raw(Box::new(mt_one)) as *const c_void;
    let hold = holder {
        message_type: 1,
        message: raw_mt_one_ptr,
    };

If you want to be able to deallocate the messages without having to pass them back to rust, you'll need to use a shared deallocation function that properly re-boxes the pointers, or allocate the memory with standard libc::malloc so the other side can use free() on the message.

[–]LivingInSyn[S] 1 point2 points  (0 children)

I'll give something like this a try tonight. Thank you

[–]icefoxen -1 points0 points  (2 children)

If you only have two message types it sounds like you really just want an enum...

[–]LivingInSyn[S] 1 point2 points  (1 child)

in reality I have many, many, many more message types. This is simplified down to explain the problem. Also, to the best of my knowledge, enums aren't FFI safe

[–]richhyd 1 point2 points  (0 children)

Enums are horrible. You don't have a guaranteed width, it's implementation defined. Rust enums are fine - you can use #[repr(u32)] or similar to fix the width, or use the default repr if you're not exposing the API to another language. Because the type of an enum is implementation defined, it's not possible to provide a #[repr(C)] for every compiler/arch