Rust 中如何将 Rust 代码暴露给 C?

推荐答案

在 Rust 中,可以通过 extern 关键字和 #[no_mangle] 属性将 Rust 代码暴露给 C 语言调用。以下是一个简单的示例:

在这个示例中,#[no_mangle] 属性用于防止 Rust 编译器对函数名进行名称修饰(name mangling),确保 C 代码可以正确链接到这个函数。extern "C" 指定了函数的调用约定为 C 语言的调用约定。

本题详细解读

1. #[no_mangle] 属性

Rust 编译器默认会对函数名进行名称修饰(name mangling),以支持函数重载等特性。然而,C 语言不支持名称修饰,因此需要通过 #[no_mangle] 属性来禁止 Rust 编译器对函数名进行修饰。这样,C 代码就可以通过函数名直接调用 Rust 函数。

2. extern "C" 关键字

extern "C" 关键字用于指定函数的调用约定为 C 语言的调用约定。Rust 和 C 有不同的函数调用约定(calling convention),extern "C" 确保 Rust 函数使用与 C 语言相同的调用约定,从而使得 C 代码可以正确调用 Rust 函数。

3. 编译为静态库或动态库

为了将 Rust 代码暴露给 C 使用,通常需要将 Rust 代码编译为静态库(.a 文件)或动态库(.so.dll 文件)。可以通过在 Cargo.toml 中配置 crate-type 来实现:

  • cdylib:生成动态库,适用于大多数跨语言调用场景。
  • staticlib:生成静态库,适用于需要将 Rust 代码静态链接到 C 项目中的场景。

4. C 代码调用 Rust 函数

在 C 代码中,可以通过声明外部函数来调用 Rust 函数。例如:

-- -------------------- ---- -------
-------- ---------

-- -- ---- --
------ --- ------- -- --- ---

--- ------ -
    --- ------ - ------ ---
    --------------- ------ --------  -- --- ------- -
    ------ --
-

5. 编译和链接

在编译 C 代码时,需要链接 Rust 生成的库文件。例如,使用 gcc 编译 C 代码并链接 Rust 生成的动态库:

其中,-L. 指定库文件的搜索路径,-lmy_rust_library 指定要链接的库文件(libmy_rust_library.solibmy_rust_library.a)。

通过以上步骤,Rust 代码就可以成功暴露给 C 语言调用。

纠错
反馈