Re: [PATCH 4/7] xdiff: make fields of xrecord_t Rust friendly
- From
Ezekiel Newren <ezekielnewren@gmail.com>
- Date
- Jul 31, 2025, 20:58 UTC
- Message-ID
- <CAH=ZcbBa=1iUTcxaBOvG_kcuWsF_nJQiWGkL+BUzsNYLpzFG5w@mail.gmail.com>
- In-Reply-To
- <ad453eee-23cd-42fe-97bd-1ff0fc2f3edf@gmail.com>
On Thu, Jul 31, 2025 at 8:20 AM Phillip Wood <phillip.wood123@gmail.com> wrote:
Show 42 quoted lines
>
> On 28/07/2025 21:14, Ezekiel Newren wrote:
> > On Mon, Jul 28, 2025 at 1:52 PM Phillip Wood <phillip.wood123@gmail.com> wrote:
> >
> > Ah, I misunderstood the scope of your question. I could not fit an
> > example of why this design pattern made sense into this patch series,
> > so I'll explain with an example here:
> >
> > If C defines a struct like below then it's obvious how to translate
> > that into rust for ffi purposes. It also makes it clear that this C
> > struct is expressly for the purpose of C <-> Rust interoperability.
> > struct some_struct {
> > u8* ptr;
> > usize length;
> > u64 counter;
> > };
> >
> > This is how that C struct needs to be defined in Rust so that it can
> > interoperate with C, and making C use the Rust types reduces the
> > chance of copy paste, and primitive type definition mismatch errors.
> > #[repr(C)]
> > pub struct some_struct {
> > ptr: *mut u8,
> > length: usize,
> > counter: u64,
> > };
>
> How is the pointer, length pair used in rust? Normally one would use a
> slice so do we have to construct a slice every time we want to use the
> data in this struct, or do we copy the data in this struct into to a an
> idiomatic struct with a slice member? If we end up copying there doesn't
> seem much point in changing all the types in the C struct as we can
> define a rust struct using *c_char, c_long etc. to interface with the C
> code and covert them to an appropriate rust type when we copy the data
> to the idiomatic version that is then used by the rust of the rust code.
> I can see the value of the typedefs for documenting C<->rust interop if
> the same struct is used by both but if we end up copying data on the
> rust side I'm not so sure.
>
> Thanks
>
> PhillipPassing pointer + length from c to Rust does not incur a memory copy overhead. Take a look at rust/xdiff/src/lib.rs wich has the following rust function defined:
#[no_mangle]
unsafe extern "C" fn xxh3_64(ptr: *const u8, size: usize) -> u64 {
let slice = std::slice::from_raw_parts(ptr, size);
xxhash_rust::xxh3::xxh3_64(slice)
}Creating a slice tells the compiler what assumptions it can make about that memory. On the C side in xdiff/xprepare.c:
extern u64 xxh3_64(u8 const* ptr, usize size);
and then it's called like this in that same file:
rec->ha = xxh3_64(rec->ptr, rec->size);
I really wanted to show my ivec type that made passing an interoperable vector type between C and Rust easy and fast, but this patch series is already getting very long.