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

Shared Type Question #330

Closed
scott-wilson opened this issue Oct 1, 2020 · 4 comments
Closed

Shared Type Question #330

scott-wilson opened this issue Oct 1, 2020 · 4 comments
Labels

Comments

@scott-wilson
Copy link

Hey, this may not be the right direction to go, but feel free to correct me.

I am wrapping a C++ library, and they've defined a struct like this:

struct Thing {
    unsigned char someenum;
}

I want to be able to directly access the struct with a Rust struct like this:

enum SomeEnum {
    A,
    B,
    C
}
struct Thing {
    someenum: SomeEnum,
}

As a test, I've tried doing something like this:

#[cxx::bridge]
mod ffi {
    enum SomeEnum {
        A,
        B,
        C,
    }

    struct Thing {
        someenum: SomeEnum,
    }
}

unsafe impl cxx::ExternType for ffi::Thing {
    type Id = cxx::type_id!("Thing");
}

But I'm probably misunderstanding how ExternType works.

Either way, is this (or something like this) possible to do in cxx currently (or will be possible in the near future)?

Thanks!

@dtolnay
Copy link
Owner

dtolnay commented Oct 1, 2020

Shared structs produce both a Rust definition and a C++ definition. If a C++ definition already exists, you can't use a shared struct for the same thing, but you can use an extern C++ type.

#[repr(u8)]
pub enum SomeEnum {
    A,
    B,
    C,
}

#[repr(C)]
pub struct Thing {
    someenum: SomeEnum,
}

unsafe impl cxx::ExternType for Thing {
    type Id = cxx::type_id!("Thing");
}

#[cxx::bridge]
mod ffi {
    extern "C" {
        type Thing = crate::Thing;
    }
}

@scott-wilson
Copy link
Author

That did the trick! Also, this is probably out of scope, but it looks like when rustfmt runs, the type Thing = crate::Thing; gets converted to type Thing;. Do you know the rustfmt rule causing that to happen, or have you run into this and know of a solution to prevent that from happening? I can create a minimal example project to demo this.

@dtolnay
Copy link
Owner

dtolnay commented Oct 1, 2020

That is a rustfmt bug rust-lang/rustfmt#4159 which was fixed in rust-lang/rustfmt#4164 but has not been released yet (:slightly_frowning_face: for a long time). I've opened rust-lang/rustfmt#4447 to backport the fix to the current released version of rustfmt.

For now you can either switch to rustfmt v2.0.0-rc.2 which contains the fix, or use #[rustfmt::skip].

@scott-wilson
Copy link
Author

I'll use the skip. Thanks!

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

No branches or pull requests

2 participants