[FFI / bindgen] getting const char * from c library, how do i use it correctly?


this is my first time using bindgen to make use of an existing c library. That library has a function that returns a c-style string as an const char * (in C), which bindgen converts to *const ::std::os::raw::c_char (Rust). For now, i want to print!() that string out to the console, and later do more stuff with it. What should i convert it to? If i understand the C library correctly, the string it returns is actually a constant that is compiled into the program, so the pointer will not be on the heap and should not be free()'d. Which of the rust string types works in a way that the memory will not be freed when an instance goes out of scope? So what should i use? I have looked at:

  • CString seems to be the obvious choice due to naming, but i’m not sure whether it will try to own the pointer and free() it when going out of scope?
  • &str seems like a good choice because it’s the type a static string would have in rust as well. how would i convert to this, since afaik &str is a fat pointer containing the string length (and the c string is null terminated). At this point, the string returned by the function is ASCII-only, but what should i think about when that is not guaranteed?
  • String - i won’t mind copying the content to an owned String, since it’s not very long, not in any performace critical path, etc, so i’d use this in case it’s less of a hassle than the other options. How would i do the conversion correctly?

Kind regards :slight_smile:

Consider CStr as well - as its docs mention, it’s the &str analog of String but for CString.

CString doesn’t hold the ptr - it will copy its data into its own buffer, and own that buffer (like String). You can go to String from CStr or CString if you want via the various conversion methods on them. If perf isn’t an issue as you say, I suggest you copy the data from the ptr into your own storage (ie CString) so you don’t risk outliving that C string if it ever becomes non-literal (I’m assuming you looked at the impl of the C lib to determine it’s returning a static literal?).

1 Like

Thank you very much, i seem to have missed CStr, and it looks like it's the perfect fit for my use case if i use CStr::from_ptr()! :slight_smile: