Returning a string from a Rust function to be called with FFI
I want an interpreted language (specifically LuaJIT) to call a Rust function that returns a string.
I am crashing before I even play the pointer.
I read that Rust strings are not null terminated, so I use a function to_c_str()
to create the string that is, but I find that the lifetimes somehow throw a key into the whole thing, since I am still a little foggy on them.
Rust code:
#![crate_type = "dylib"] extern crate libc; #[no_mangle] pub extern "C" fn hello_world() -> std::c_str::CString { "Hello World".to_c_str() }
Lua code:
local ffi = require("ffi") ffi.cdef[[ char *hello_world(); ]] local hello_world = ffi.load("hello_world") local hw = hello_world.hello_world()
source to share
A CString
is not only a pointer; it is a pointer plus a boolean indicating whether the CString
string belongs to C. Because of this, the declaration in your Lua code does not match the definition in your Rust code.
Return a *const c_char
or *mut c_char
using a method unwrap
on CString
. If your function returns a dynamically allocated string, you also need to provide a function to free the string, which Lua code needs to call manually, otherwise it will leak memory.
source to share
Francis Gagné's answer is correct. Here's a complete working solution.
Rust code:
#![crate_type = "dylib"] extern crate libc; #[no_mangle] pub extern "C" fn hello_world() -> *const libc::c_char { unsafe { "Hello World".to_c_str().unwrap() } }
Lua code:
local ffi = require("ffi") ffi.cdef[[ char *hello_world(); ]] local hello_world = ffi.load("hello_world") local hw = ffi.string(hello_world.hello_world())
source to share