首页 文章

从Rust函数返回一个字符串,用FFI调用

提问于
浏览
3

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

在我取消引用指针之前我崩溃了什么 .

我读到Rust字符串不是以null结尾的,所以我使用 to_c_str() 函数来创建一个字符串,但是我认为生命周期在某种程度上会在整个事情中抛出一个扳手,因为我对它们仍然有些模糊 .

锈码:

#![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()

2 回答

  • 1

    CString 不仅是一个指针; it's a pointer plus a boolean表示 CString 是否拥有C字符串 . 因此,Lua代码中的声明与Rust代码中的定义不匹配 .

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

  • 5

    Francis Gagné's answer是正确的 . 这是完整的工作解决方案 .

    锈码:

    #![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())
    

相关问题