诉求:

C和rust交叉编译,C语言调用rust,C语言数据通过struct传递rust,rust将C语言的数据结构转换成rust内部数据,在rust内部完成相应的逻辑计算后输出结果返回给C调用,举一个简单案例说明。

新建工程

│ CMakelists.txt
│ compile.bat
│
├─build
├─rust_lib
│ │ .gitignore
│ │ Cargo.lock
│ │ Cargo.toml
│ │
│ └─src
│ lib.rs
│
└─src
main.c

rust_lib\src\lib.rs

#[repr(C)]
pub struct Input {
    pub a: i32,
    pub b: i32,
}

#[repr(C)]
pub struct Output {
    pub result: i32,
}

#[unsafe(no_mangle)]
pub extern "C" fn compute_square_sum(input: Input) -> Output {
    let sum = input.a * input.a + input.b * input.b;
    Output { result: sum }
}

rust_lib\Cargo.toml

[package]
name = "rust_lib"
version = "0.1.0"
edition = "2024"

[dependencies]

[lib]
crate-type = ["staticlib"]  // 将rust编译成静态库

src\main.c

#include <stdio.h>

struct Input {
    int a;
    int b;
};

struct Output {
    int result;
};

extern struct Output compute_square_sum(struct Input);

int main() {
    struct Input in = {3, 4};
    struct Output out = compute_square_sum(in);
    printf("Square sum: %d\n", out.result);  // 应输出 25
    return 0;
}

通过CMakeLists.txt管理工程

CMakelists.txt

cmake_minimum_required(VERSION 3.14)
project(CRustExample LANGUAGES C)

# 设置构建类型(Release 更适合 Rust)
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif()

# 设置 Rust 工具链路径(可选,通常自动检测)
find_program(CARGO cargo REQUIRED)

# 定义目标名称
set(RUST_LIB_NAME rust_lib)
set(RUST_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/rust_lib)
set(RUST_LIB_OUTPUT_DIR ${RUST_LIB_DIR}/target/release)
set(RUST_STATIC_LIB ${RUST_LIB_OUTPUT_DIR}/${RUST_LIB_NAME}.lib)

# 构建 Rust 静态库
add_custom_command(
    OUTPUT ${RUST_STATIC_LIB}
    COMMAND ${CARGO} build --release --manifest-path ${RUST_LIB_DIR}/Cargo.toml
    WORKING_DIRECTORY ${RUST_LIB_DIR}
    COMMENT "Building Rust static library..."
    VERBATIM
)

# 定义一个假的目标来代表 Rust 库
add_custom_target(RustLibTarget
    DEPENDS ${RUST_STATIC_LIB}
    SOURCES ${RUST_LIB_DIR}/src/lib.rs ${RUST_LIB_DIR}/Cargo.toml
)

# 添加 C 可执行文件
add_executable(main src/main.c)

# 确保先构建 Rust 库
add_dependencies(main RustLibTarget)

# 包含 Rust 源码目录(用于编译时可见性,非必须)
target_include_directories(main PRIVATE ${RUST_LIB_DIR}/src)

# 链接 Rust 静态库
target_link_libraries(main ${RUST_STATIC_LIB})

# 链接 Rust 所需的系统库(pthread, dl, etc)
target_link_libraries(main
    pthread
    # dl      # windows 不需要
    # rt      # Linux only  windows 不需要
    gcc_s   # for unwinding
)

# 设置链接器语言为 C,避免 CMake 自动使用 C++ 链接器
set_property(TARGET main PROPERTY LINKER_LANGUAGE C)

在Windows下通过脚本组织命令

@echo off
setlocal

set "DIR=build"

:: 删除目录(如果存在)
if exist "%DIR%" (
    echo Deleting directory: %DIR%
    rmdir /s /q "%DIR%"
)

:: 重新创建目录
echo Creating directory: %DIR%
mkdir "%DIR%"

echo Done.

cd "%DIR%"

cmake .. -G "Ninja"
ninja

执行结果

Square sum: 25

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐