11个版本
0.2.4 | 2023年12月24日 |
---|---|
0.2.3 | 2023年12月20日 |
0.2.0 | 2023年1月13日 |
0.1.5 | 2022年3月21日 |
在FFI中排名第127
每月下载量56
10KB
155 行
c_import
这是一个提供c_import宏(同时也有cpp_import宏)的小型proc宏crate,可用于将C头文件导入到你的程序中。它利用了bindgen,因此需要在你的系统中安装bindgen。它也支持no_std模式。
使用方法
在你的Cargo.toml文件中
# Cargo.toml
[depenedencies]
c_import = "0.2"
在你的Rust源文件中
// src/main.rs
use c_import::c_import;
c_import!(
"<stdio.h>",
"<cairo/cairo.h>",
"--link cairo"
);
fn main() {
let version = unsafe { cairo_version() };
println!("{}", version);
}
如果你不使用--link
指令,你可以使用Rust构建脚本
// build.rs
fn main() {
println!("cargo:rustc-link-lib=cairo");
}
使用非系统头文件也是可能的,通过用引号包围头文件路径
// src/main.rs
use c_import::c_import;
c_import!("src/my_header.h");
fn main() {
let version = unsafe { cairo_version() };
println!("{}", version);
}
额外的clang参数
你可以将额外的clang参数作为宏的额外参数传递
// src/main.rs
use c_import::c_import;
c_import!(
"src/my_header.h",
"-DMY_DEFINE",
"-I/somepath/include"
);
fn main() {
let version = unsafe { cairo_version() };
println!("{}", version);
}
类似地,你可以调用像pkg-config这样的工具来检索cflags并将它们传递给bindgen
use c_import::c_import;
c_import!(
"<cairo.h>",
"<stdio.h>",
"$pkg-config --cflags cairo"
);
fn main() {
let version = unsafe { cairo_version() };
println!("{}", version);
}
宏参数
- 正常参数被认为是头文件。
- 以
--link
开头的参数用于向生成的extern函数插入#[link (name = libname)]
属性,这允许链接库而不必显式创建包含println!("cargo:rustc-link-lib=libname");
的build.rs文件 - 以
--
开头的参数被认为是bindgen参数。 - 以
-
开头的参数被认为是cflags,如包含路径或定义(分别对应"-I"和"-D")。 - 以
$
开头的参数被认为是shell命令,它们返回cflags,类似于pkg-config。
使用C++头文件(有限制)
// src/main.rs
use c_import::cpp_import;
cpp_import!("<FL/Fl.H>");
fn main() {
let version = unsafe { Fl::api_version() }; // static method of class Fl
println!("{}", version);
}
// build.rs
fn main() {
println!("cargo:rustc-link-lib=fltk");
}
另一个示例展示了如何处理C++命名空间
// src/my_header.hpp
#pragma once
namespace my_namespace {
class MyStruct {
int version_;
public:
MyStruct(int version);
int version() const;
};
}
// src/main.rs
use c_import::cpp_import;
cpp_import!("src/my_header.hpp");
fn main() {
let h = unsafe { my_namespace_MyStruct::new(2) };
println!("{}", unsafe { h.version() });
}
限制
- 主要是bindgen的限制
- 使用C++头文件。
- 使用静态内联函数。