【Rust】C和Rust交叉编译
诉求:
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); // 应输出 25return 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.tomlWORKING_DIRECTORY ${RUST_LIB_DIR}COMMENT "Building Rust static library..."VERBATIM
)# 定义一个假的目标来代表 Rust 库
add_custom_target(RustLibTargetDEPENDS ${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(mainpthread# dl # windows 不需要# rt # Linux only windows 不需要gcc_s # for unwinding
)# 设置链接器语言为 C,避免 CMake 自动使用 C++ 链接器
set_property(TARGET main PROPERTY LINKER_LANGUAGE C)
在Windows下通过脚本组织命令
@echo off
setlocalset "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
