【问题标题】:Call Rust with arguments使用参数调用 Rust
【发布时间】:2021-01-20 03:57:50
【问题描述】:

我一直在尝试使用多个字符串参数从 C 中调用 Rust 函数,但由于某种原因,唯一发送的参数是第一个。这是我尝试过的:

输入.c

extern void print_str(char str1, char str2);

void c_function() {
    scanf("%s %s", str1, str2);
    print_str(str1, str2);
}

lib.rs:

#[no_mangle]
pub extern "C" fn print_str(str1: &str, str2: &str) {
    unsafe {
       libc::printf(str1.as_ptr() as *const libc::c_char);
       libc::printf(str2.as_ptr() as *const libc::c_char);
    }
}

【问题讨论】:

  • Rust 代码 issues a warning: "extern fn 使用类型 str,这不是 FFI 安全的" 建议:"考虑使用*const u8 和一个长度,字符串切片没有 C 等效项"
  • 并且,在 C 中,charconst char * 不同。您打算提供字符串,但您的 C 声明需要两个 single 字符。

标签: c rust arguments ffi


【解决方案1】:

首先,您提供的代码被直接破坏了,C sn-p 完全没有意义。

其次,你的类型完全不匹配。

&str 是 Rust 类型,C 没有等效的内置类型,而且它肯定不等同于 C 字符串,它的低级有效负载(底层缓冲区)甚至与 C 字符串不兼容,因为 Rust 字符串不是以 nul 结尾的。编译器从字面上告诉你:

warning: `extern` fn uses type `str`, which is not FFI-safe
 --> src/lib.rs:2:35
  |
2 | pub extern "C" fn print_str(str1: &str, str2: &str) {
  |                                   ^^^^ not FFI-safe
  |
  = note: `#[warn(improper_ctypes_definitions)]` on by default
  = help: consider using `*const u8` and a length instead
  = note: string slices have no C equivalent

此外,从 C 端,您发送的是 char,甚至不是 C 字符串。

所以你在这里做的是发送两个字符,告诉 Rust 它们实际上是两个 rust 字符串,然后将 that 误用作两个 C 字符串,你的代码有和它一样多的 UB有线条。

Rust 函数应该采用 *mut c_char,而 C 函数 extern 应该定义为采用两个 char*

【讨论】:

  • 即使使用错误的类型,我也能正常工作。
  • 不,你没有“让它工作”。因为无法在 FFI 情况下检查类型,所以编译它,编译器只能相信你知道自己在做什么。
  • 它运行,对我来说这才是真正重要的。
  • 你是你,只是当事情随机不起作用时请不要回来问问题:尽管有相反的建议,但你的代码是不安全的,你的代码是 UB 中心的。跨度>
【解决方案2】:

C 代码:

extern void print_str(char *str1, char *str2);

void c_function() {
   char str1[10];
   char str2[10];
   scanf("%s "%s", str1, str2);
   print_str(str1, str2);
}

锈代码:

#[no_mangle]
pub extern "C" fn print_str(str1: &str, str2: &str) {
    unsafe {
        libc::printf(str1.as_ptr() as *const c_char);
        libc::printf(str2.as_ptr() as *const c_char);
    }
}

【讨论】:

  • 这是不正确的。你的签名对它的预期撒谎。
猜你喜欢
  • 2015-09-23
  • 2018-04-14
  • 2021-04-23
  • 1970-01-01
  • 1970-01-01
  • 2020-04-17
  • 2015-11-05
  • 1970-01-01
相关资源
最近更新 更多