Generating Rust FFI Bindings to C Libraries


#1

Dear Rust users,

I use bindgen to generate the links between my C lib and my Rust program.

I have a structure defined in the libgw.h and implemented in the libgw.c that I can not use.
In binding.rs my struct is defined as :

# [ repr ( C ) ]
# [ derive ( Debug , Copy , Clone ) ]
pub struct gwnet_ctxt { _unused : [ u8 ; 0 ] , }

but in libgw.c my struct is defined as :

struct gwnet_ctxt {
    gwnet_itf_type_t itf_type;
    bool is_publisher;
    void *zmq_sock;
    char pcap_error[PCAP_ERRBUF_SIZE];
};

(gwnet_itf_type is an enum defined in libgw.c that does not appear also in binding.rs)

I’d be very happy if someone could tell me how to resolve the problem


#2

This is probably because the .h file defines it as an opaque struct:

struct gwnet_ctxt;

so effectively the C header wants to make the struct fields private.

If you copy the full definition to the .h file, or generate bindings from the .c file, you should get the full definition. But beware – if the header tried to hide the fields, there may be a good reason for it.

The binding with “_unused” field is fine if you only plan to use pointers to this struct. This is often the right solution, as libraries offer functions to access the struct via an opaque pointer, instead of allowing the struct fields to be accessed directly.


#3

I would like to call a function in my C lib that takes as parameter : (const *char const )

I don’t know if there is a simple way to convert a Rust Str into * c_char ?

Thank you for helping me :slight_smile:


#4

Rust’s str/String is not 0-terminated, so it can’t be easily converted to *c_char.

You will need to make a copy of the string in CString and use CString's as_ptr(). Be careful not to free the CString while C is still using it.


#5

Thanks