Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help with enum of Box through FFI #64033

Closed
marmeladema opened this issue Aug 31, 2019 · 1 comment
Closed

Help with enum of Box through FFI #64033

marmeladema opened this issue Aug 31, 2019 · 1 comment

Comments

@marmeladema
Copy link
Contributor

Hello everyone!

I am having an issue understanding how to share an Enum, where some variants holds a Box, through FFI boundary.
The Enum looks like this:

#[derive(Debug)]
#[repr(C)]
pub enum SchemeType {
    Ip,
    Bytes,
    Int,
    Bool,
    Array(Box<SchemeType>),
    Map(Box<SchemeType>),
}

At the beginning I thought it would not possible to share this type with C directly, but then I found https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md
So after reading that RFC, I thought that the C type equivalent type would be something like:

typedef enum {
    SCHEME_TYPE_TAG_IP,
    SCHEME_TYPE_TAG_BYTES,
    SCHEME_TYPE_TAG_INT,
    SCHEME_TYPE_TAG_BOOL,
    SCHEME_TYPE_TAG_ARRAY,
    SCHEME_TYPE_TAG_MAP,
} scheme_type_tag_t;

typedef struct {
    scheme_type_tag_t tag;
    void *data;
} scheme_type_t;

You can find the code here: marmeladema/rust-ffi-enum-box@8d61450

This did not worked well, and crashed in the test functions with Illegal instruction.
I read this issue #52976 but its still not clear at all if Box<T> can be represented directly with a pointer. Its currently not #[repr(transparent)] so I guess until it is, it cannot safely be done.

After trying different things, i figured that adding 8 bytes padding to the end of scheme_type_t worked, at least on x86_64: marmeladema/rust-ffi-enum-box@2bc030e

But this does not work at all on aarch64.

The question is then, how should I approach this issue?
I figured the best way might be add a FFI-compatible SchemeTypeFFI wrapper, (storing a raw pointer instead of a Box<T> and convert back and forth from and to real Rust SchemeType type:

pub enum SchemeTypeFFI {
    Ip,
    Bytes,
    Int,
    Bool,
    Array(*mut SchemeType),
    Map(*mut SchemeType),
}

Thank you in advance for your help!

@jonas-schievink
Copy link
Contributor

Hi! This issue tracker is mainly meant for bug reports and concrete, small feature requests. Questions like this are better asked in the user forum at https://users.rust-lang.org/ or on one of the chat platforms used by the Rust community.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants