【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); // 应输出 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
更多推荐

所有评论(0)