'Cannot share C++ struct with Rust using CXX bridge

I understand C++ class definitions must be hidden behind a pointer (*mut, SharedPtr<T>, etc). But structs seem like they should be "C like".

I am trying to export CleanupParameters to the Rust side of the binding.

If I put the struct definition in the root of the CXX bridge module like:

#[cxx::bridge(namespace = "RDKit")]
pub mod ffi {
    pub struct CleanupParameters {
        rdbase: String,
    }
    
    unsafe extern "C++" { /* snip */ }
}

I get the compiler error:

warning: ..../rdkit-sys/src/cxx/bridge/mol_standardize.rs.cc:87:10: error: definition of type 'CleanupParameters' conflicts with type alias of the same name
warning:   struct CleanupParameters;
warning:          ^

which makes sense, it's like I'm defining a new CleanupParameters and not "adopting" the C++ definition, so the name collision makes sense.

But if I try to move the definition in to the extern block:

#[cxx::bridge(namespace = "RDKit")]
pub mod ffi {
    unsafe extern "C++" {   
        pub struct CleanupParameters {
            rdbase: String,
        }
    }
}

the language is not allowed by the CXX bridge proc macro:

  error[cxxbridge]: expected one of: `fn`, `static`, `type`
    ┌─ src/cxx/bridge/mol_standardize.rs:7:13
    │
  7 │         pub struct CleanupParameters {
    │             ^^^^^^ expected one of: `fn`, `static`, `type`

which does not make much sense. How can I share "non opaque" structs from C++ into Rust?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source