gpt4 book ai didi

rust - 如何生成具有 `main` 类接口(interface)的 FFI 函数?

转载 作者:行者123 更新时间:2023-12-03 11:36:11 25 4
gpt4 key购买 nike

我正在尝试使用 rust 与一个古老的平台交互,该平台期望函数以特定的 C 样式格式声明和外部化。

char *func(int argc, char *argv[])
我正在尝试在 Rust 中重现此签名。我需要能够正确解析参数(最好是 Rust 字符串),然后在不破坏签名的情况下将任意值作为字符串返回。
到目前为止,我有以下内容:
#[no_mangle]
pub extern "C" fn my_function(argc: isize, argv: *const c_char) -> (CString) {

let output: CString = CString::new("Test Output").expect("CString::new failed");

return output;
}
它通过接口(interface)正确返回我的测试字符串,但我不知道如何将 argv 解析为可用格式,或者我的 argv 实现是否正确符合指定格式。我不熟悉指针,我什至不知道从哪里开始弄清楚这一点。

最佳答案

使用您现有的代码,您有几个主要问题:

  • argv: *const c_char是错误的,因为原始 C 代码是一个指针数组,而不是指向 char 的指针。正确的类型是
    argv: *const *const c_char
  • 您不能返回 CString因为那不是 C 知道如何处理的类型。您需要返回*mut c_char就像 C 函数一样。为此,您使用 output.into_raw() 解开字符串并获取底层 *mut c_char指针。这也意味着你给这个 C 代码一个随机指针,它可以将它作为一个 C 字符串读取,但它不能释放那个内存,所以你要么泄漏了那个内存,要么你需要第二个函数来传递返回 Rust 的字符串,稍后使用 from_raw 释放.在这种情况下,我使用 *mut c_char因为那是into_raw返回。
  • 您应该始终使用 c_ C 接口(interface)中所有内容的类型,包括 argc ,例如
    my_function(argc: c_int, argv: *const *const c_char) -> *mut c_char

  • 要处理 args,您需要遍历 argc将每个指针包装成 CStr 的值,然后您可以使用它而无需担心不安全的代码。
    全部放在一起:
    #[no_mangle]
    pub extern "C" fn my_function(argc: c_int, argv: *const *const c_char) -> *mut c_char {

    let argv: Vec<_> = (0..argc)
    .map(|i| unsafe { CStr::from_ptr(*argv.add(i as usize)) })
    .collect();

    // Whatever processing you need to do.

    let output = CString::new("Test Output").expect("CString::new failed");

    return output.into_raw();
    }
    并且可能
    #[no_mangle]
    pub extern "C" fn my_function_free(s: *mut c_char) {
    unsafe {
    CString::from_raw(s);
    }
    }

    关于rust - 如何生成具有 `main` 类接口(interface)的 FFI 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66308588/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com