C++ std::function types are translated into [u128; 3usize]
header.hpp:
using example_type = std::function<void()>;
bindgen invocation:
let bindings = bindgen::Builder::default()
.header("header.hpp")
.opaque_type("std::.*")
.whitelist_type("example_type")
.rust_target(bindgen::RustTarget::Nightly)
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.generate()
.expect("Unable to generate bindings");
Output binding:
pub type example_type = [u128; 3usize];
With just a plain typedef like this all is well, but in many situations bindgen also needs to use this type (possibly indirectly) in an extern "C" {...} block, resulting in warnings like this:
warning: `extern` block uses type `[u128; 3usize]`, which is not FFI-safe
--> src/../bindings.rs:9772:18
|
9772 | root::example_type;
| ^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= help: consider passing a pointer to the array
= note: passing raw arrays by value is not FFI-safe
warning: `extern` block uses type `u128`, which is not FFI-safe
--> src/../bindings.rs:1230:27
|
1230 | this: *const root::example_type,
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= note: 128-bit integers don't currently have a known stable ABI
While not strictly an error, it makes me uneasy that function pointers may or may not be interpreted correctly between the C++ library I need to use and my own code.
Is there a way to get bindgen to generate, say, &[u64; 6usize] or something for std::functions instead? Is this intended behavior or unexpected?
I have a feeling this could be related to the use of .opaque_type("std::.*"), but whitelisting std::function doesn't seem to change anything and I'd greatly prefer not to generate bindings for all of std.
Yes, this is what opaque_type causes when used on this kind of stuff... That being said, it seems to me it's a rust bug to complain that *const root::example_type is not FFI-safe...
That being said, it seems to me it's a rust bug to complain that
*const root::example_typeis not FFI-safe...
https://github.com/rust-lang/rust/issues/66220 Enjoy :)
Out of curiosity, why is this mapping happening? Does this array represent multiple pointers (context, parameters and return value?) or what does it mean semantically?
Out of curiosity, why is this mapping happening?
This related issue https://github.com/rust-lang/rust-bindgen/issues/2071#issuecomment-882329820 states that basically the example_type should not be translated by bindgen, but since bindgen does it anyway, the user should blocklist it manually.