Return string by reference

I want to develope a Rust function equivalent to next c function which returns a string by reference for a DLL

int EXPORT test(char** str, int len)
{
*str = "hello worl";

 return 1;

}

I guess it should be something like this but its not running:

#[no_mangle]
unsafe fn createModel4rust(str: *mut *const c_char, len: i32 ) -> i32 {
let c_str_2 = CString::new( "hello worl").unwrap();
strncpy(*str, c_str_2.as_ptr(), len as usize);
1
}

Do you know how to do it right? Thanks

Your c_str_2 is a local variable. When it goes out of scope, its destructor (Drop impl) is run and the underlying buffer is deallocated, meaning that you ultimately write a dangling pointer to the out parameter.

If you want to transfer ownership to a (necessarily manually-managed) raw pointer, then use CString::into_raw() instead. Playground


Also note that when you have a char ** out parameter, then you are likely not supposed to strcpy() onto the inner pointer. If there were a pre-allocated buffer, then it would be sufficient to pass a char * and strcpy()/memcpy() into it. Instead, it is likely that there is no such pre-allocated buffer and you are supposed to fill in the buffer pointer itself with a newly-allocated pointer (which is my example above does).

3 Likes

Looks like you need this:

#[no_mangle]
unsafe extern fn test(s: *mut *const u8, _len: i32) -> i32 {
    *s = "hello worl\0".as_ptr();
    1
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.