Problem having using one c api in rust

I am having one c api which i need to call from rust side

int Convert(char *inputData, unsigned int nDataLen, char * outputData, unsigned int nOutLen);

We pass data to be converted to inputData arr and get output on OutputData arr. The nDataLen and nOutLen are the size of input and output arr respectively.

The size of inputData and OutputData can only be 5000 bytes long at a time.
The inputData is opus encoded audio I get from azure api.

I am using bindgen and it generated the following binding

extern "C" {
    pub fn Convert(
        inputData: *mut ::std::os::raw::c_char,
        nDataLen: ::std::os::raw::c_uint,
        outputData: *mut ::std::os::raw::c_char,
        nOutLen: ::std::os::raw::c_uint,
    ) -> ::std::os::raw::c_int;
}

I am trying to test this code using following

            let mut input_data: Vec<u8> = read_data.unwrap(); 
            let mut truncated_data = &input_data[0..5000];

            let input_len = input_data.len() as u32;
            let mut output_data = vec![0i8; 5000];
            let output_len = 5000;

            let result = Convert(
                truncated_data.as_ptr() as *mut i8, 
                input_len,
                output_data.as_mut_ptr(),
                output_len,
            );

I am getting SIGSEGV: invalid memory reference while trying to use the above code. Can someone please help

One issue might be that you get your input len from the original data and not the truncated one. So input_len could be larger than 5000 and that could lead the c function to go out of bounds of the output buffer.
Also if the C function modifies the input buffer you should create a mutable reference to it, not a shared one.

2 Likes

oh ok my bad
yeah it is working now!

Regarding your other point

This will create a mutable reference to it right?

Pardon me if I am asking something silly. I am new to rust

If you have this, then writing to input_data is UB, that's what they are trying to say. You need let truncated_data = &mut input_data[0..5000] and truncated_data.as_mut_ptr, correspondingly.

2 Likes

oh ok got it.
thanks!

will this create an immutable reference to input_data. If so then is declaring truncated data like let mut truncated_data equivalent to let truncated_data ?

let mut xxx doesn't mean that the value stored in the variable xxx is mutable. It means that the variable/binding xxx can be reassigned to a different value. So without the mut you wouldn't be able to reassign truncated_data like this, for example:

let mut truncated_data = &input_data[0..5000];
// then later:
truncated_data = &input_data[5001..10000];
2 Likes