Closed scott-wilson closed 10 months ago
When you are using "shared structs", the idea is that the cxx-bridge is the "source of truth" that provides the definition used in both the C++ and the Rust code.
The way this works in your example is that cxx
generates a struct definition for ROI
in the imageio.rs.cc
file, and then the macro expansion on the Rust side also generates the Rust struct analogous to this.
The reason you are getting those errors is because now you indeed have two conflicting definitions of ROI
: the one that cxx
is generating, and the one you are including from <OpenImageIO/imageio.h>
which you bind with using ROI = OIIO::ROI
.
It may be the case that these definitions are structurally equivalent but -- as far as the C++ compiler is concerned -- they are two distinct type definitions (at different locations) using the same name, so it complains.
What you actually want to do in your example (since ROI
is already defined by the C++ side) is refactor it in the following way:
imageio.rs
// ROI
#[repr(C)]
pub struct ROI {
pub xbegin: i32,
pub xend: i32,
pub ybegin: i32,
pub yend: i32,
pub zbegin: i32,
pub zend: i32,
pub chbegin: i32,
pub chend: i32,
}
// This is necessary (particularly the `Kind = cxx::kind::Trivial`) if you are going to treat `ROI` as a trivial
// type, which allows you to be able to return the type by-value (for `roi_default`) without wrapping
// in a pointer type. (NOTE: you shouldn't actually do this though if it's not trivial)
unsafe impl cxx::ExternType for ROI {
type Id = cxx::type_id!("oiio::ROI");
type Kind = cxx::kind::Trivial;
}
#[cxx::bridge(namespace = oiio)]
mod ffi {
unsafe extern "C++" {
include!("oiio-sys/include/ffi_imageio.h");
// refer to the already defined Rust `ROI` type, which can also be placed in completely separate module
type ROI = crate::imageio::ROI;
// ROI
pub fn roi_default() -> ROI;
}
}
That seems to do the trick. Thanks!
Hey all, I have a library that I'm wrapping that contains a struct that looks like this:
OpenImageIO/imageio.h
I want to be able to treat this as a shared type, so I have some code that looks like this:
ffi_imageio.h
ffi_imageio.cpp
imageio.rs
Yet, I'm getting the following compile error:
What am I doing wrong in this case? I thought that the ROI should be defined on the Rust side, and found on the C++ side. Or, is there a way to say "Hey, there's a struct in Rust that looks like this, and there's an exact copy of this on the C++ side. Use that one."?