I’m writing a Rust wrapper for a C++ library using cxx.
One frequently encountered data type in this library are vectors of variable size, where each element is a vector of fixed size – e.g. an N-length vector containing N three-dimensional points, each made up of 3 doubles.
Looking at the cxx supported bindings, it seems like the obvious way is something like the below, binding Vec<[u64; 3]>
to rust::Vec<std::array<uint64_t, 3>>
:
// main.rs
include!("include/foo.h");
#[cxx::bridge]
pub mod ffi {
unsafe extern "C++" {
fn foo(x: Vec<[u64; 3]>);
}
}
// foo.h
void foo(rust::Vec<std::array<uint64_t, 3>> x);
However, this produces the following error:
error[cxxbridge]: unsupported element type of Vec
┌─ src/main.rs:17:19
│
17 │ fn foo(x: Vec<[u64; 3]>);
│ ^^^^^^^^^^^^^ unsupported element type of Vec
Solutions that do work, but aren’t ideal:
-
Creating a shared struct, like
Point3D
, and usingVec<Point3D>
. Annoying because I’d need a new struct for every variation of N. It’s also not clean, because (in the case of 3D points) I have data types in Rust and C++ already for representing points, so this type is really only used in the bridge. -
Flattening into a
Vec<u64>
and then unflattening to some Rust type. Fine if it’s the only way, but feels a little messy.
I was hoping there would be a cleaner way, before I start repeating this pattern all over for all of the various methods I need to cover in my wrapper.