使用参数调用 Rust

问题描述

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

input.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);
    }
}

解决方法

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

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

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

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*

,

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);
    }
}