将一个 Rust 函数返回的字符串用 FFI 调用。

我想让一个解释语言(特别是LuaJIT)调用一个返回字符串的Rust函数。

我的代码在我解引用指针之前就崩溃了。

我读到Rust字符串没有空终止符,所以我使用了to_c_str()函数来生成一个空终止的字符串,但是我认为生命周期在整个过程中产生了问题,因为我对它们仍然有点模糊。

Rust 代码:

#![crate_type = "dylib"]

extern crate libc;

#[no_mangle]
pub extern "C" fn hello_world() -> std::c_str::CString {
    "Hello World".to_c_str()
}

Lua 代码:

local ffi = require("ffi")
ffi.cdef[[
char *hello_world();
]]

local hello_world = ffi.load("hello_world")
local hw = hello_world.hello_world()
点赞
用户234590
用户234590

CString 不仅是一个指针;它是一个指针加上一个布尔值,这个值指示 CString 是否拥有 C 字符串。因此,你 Lua 代码中的声明与 Rust 代码中的定义不匹配。

通过在 CString 上使用 unwrap 方法返回一个 *const c_char*mut c_char。如果你的函数返回一个动态分配的字符串,你还需要提供一个函数来释放该字符串,Lua 代码需要手动调用,否则将导致内存泄漏。

2014-10-26 07:20:25
用户155423
用户155423

Francis Gagné的答案是正确的。以下是完整的工作解决方案。

Rust代码:

#![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代码:

local ffi = require("ffi")
ffi.cdef[[
char *hello_world();
]]

local hello_world = ffi.load("hello_world")
local hw = ffi.string(hello_world.hello_world())
2016-09-16 19:26:41