How to pass a C struct to Rust?

I've found https://rust-embedded.github.io/book/interoperability/c-with-rust.html which teaches how to pass a C Struct to Rust. However, it uses the cty crate, which have to be generated by some kind of script.

I want to do things more easily as there is very few things I need to pass. Just some strings (char*) and numbers.

I already sucessfully passed a single uint8_t from C to Rust.

I'm now trying this on the Rust side:

#[repr(C)]
pub struct VPNParameters {
    pub address: *mut c_char,
    pub address_size: usize,
    pub x: c_int,
}

#[no_mangle]
pub extern "C" fn passParameters(vpnParameters: *mut VPNParameters)
{
    //error: says "vpnParameters" has no address field
    println!("{}", vpnParameters.address);
}

and on C++:

struct VPNParameters {
    char* address;
    size_t address_size;
    int x;
} VPNParameters;

extern "C" void passParameters(VPNParameters* vPNParameters);

I think it's something like that. But why I can't access the struct members on Rust? And possibly it won't work either, I may need to convert the char to a string.

I guess this would work:

println!("{}", unsafe { *vPNParameters.address(i as isize) });

Raw pointers must be explicitly dereferenced.

#[repr(C)]
pub struct VPNParameters {
    pub address: *mut c_char,
    pub address_size: usize,
    pub x: c_int,
}

#[no_mangle]
pub extern "C" fn passParameters(vpnParameters: *mut VPNParameters)
{
    unsafe {
        println!("{:?}", (*vpnParameters).address);
    }
}
1 Like

this ends up printing the address of the variable address, not the text contained in it. Is it possible to print the text using println!?

Not directly. Rust has no idea that a *mut c_char is sometimes a pointer to a null-terminated string.

You use std::ffi::CStr to convert to a Rust slice.

2 Likes

If the address is a null terminated string, you can create a CStr. You can then use to_str to try to get a &str slice of the data (which would fail if it is not valid utf-8). You can also use to_string_lossy.

3 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.