Search code examples
luarustffiluajit

Returning a string from a Rust function to be called with FFI


I want to have an interpreted language (specifically LuaJIT) call a Rust function that returns a string.

What I have crashes before I even dereference the pointer.

I read that Rust strings are not null-terminated, so I am using the to_c_str() function to make a string that is, but I figure lifetimes are somehow throwing a wrench in the whole thing since I am still somewhat foggy about 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()

Solution

  • A CString isn't only a pointer; it's a pointer plus a boolean that indicates if the CString owns the C string. Because of this, the declaration in your Lua code doesn't match the definition in your Rust code.

    Return a *const c_char or a *mut c_char by using the unwrap method on CString. If your function returns a dynamically allocated string, you also need to provide a function to free the string that the Lua code needs to call manually, otherwise it will cause a memory leak.