Recommended way of FFI of generic Rust

Background

Rust generic is a very powerful concept. With a well-encapsulated library, the down-stream users can really achieve "write one code, fit into multiple situations" without any runtime overhead.

For example:

trait Common {
    type Field;
}

struct Comm1;
impl Common for Comm1 {
    type Field = u64;
}
struct Comm2;
impl Common for Comm2 {
    type Field = u32;
}

struct Foo<C: Common> {
    field: C::Field,
}

fn util<C: Common>(foo: &Foo<C>) { /* ... */ }

Then the down-stream users can manipulate both Foo<Comm1> and Foo<Comm2> with util and more functions generic over C: Common:

fn my_downstream_impl<C: Common>(foo: &Foo<C>) {
    let field = &foo.field;
    util(foo);
    // ...
}

Problem

What is the best practice to expose those generics to C/Python/... via FFI?

In a simplest solution, we can just define extern FFI functions:

#[no_mangle]
extern "C" fn util_comm1(foo: *const Foo<Comm1>) { /* ... */ }

#[no_mangle]
extern "C" fn util_comm2(foo: *const Foo<Comm2>) { /* ... */ }

Then the C/Python side could just use those functions.

However, in this solution, C/Python side could not achieve the "write one code, fit into multiple situations" goal. They must write:

void my_downstream_impl_comm1(void *foo) {
    util_comm1(foo);
}

void my_downstream_impl_comm2(void *foo) {
    util_comm2(foo);
}

To workaround this problem, C could use macros:

// comm1.h
#define FIELD uint64_t
#define util util_comm1

// comm2.h
#define FIELD uint32_t
#define util util_comm2

// rust-ffi.h
struct Foo {
    FIELD field;
}
void util(struct Foo *foo);

// downstream.c
#include "comm1.h"
#include "rust-ffi.h"

void my_downstream_impl(struct Foo *foo) {
    FIELD field = foo->field;
    util(foo);
}

To make this code fit into both Comm1 and Comm2, the above code should be compiled twice into two binaries, with different headers included.

I don't know if this approach is the best practice to handle this problem, and I really want to know how to do this right and best in C/Python FFI situations.