Sending Strings to C Functions
Let's go back to our project. Let's add another C function.
// Header
int string_length(const char* s);
// Body
#include <string.h>
int string_length(const char* s) {
return strlen(s);
}
This function will explode nicely if we don't null-terminate our string - and yield a length otherwise. Let's handle some ways to make a string to pass to it:
For constants, my favourite is the relatively new c literal syntax.
#![allow(unused)] fn main() { #[test] fn test_string_length() { // Use a Rust "C string literal" to create a null-terminated string let s = c"Hello!"; let len = unsafe { string_length(s.as_ptr()) }; assert_eq!(6, len); } }
Prior to this code, you'd need:
#![allow(unused)] fn main() { let s = "Hello!"; let s_c = std::ffi::CString::new(s).unwrap(); let len = unsafe { string_length(s_c.as_ptr()) }; assert_eq!(6, len); }
Go ahead and test that, too. You can use that with any Rust type that breaks down to &str, so now you can make C strings dynamically.
The
unwrapis there becauseCStringchecks that you haven't included any null/0 bytes in the string. That would be bad on the C side. It also guarantees that it will add the zero to the end. So you're adding safety!