在Go中调用Rust动态库
2020/07/29
posted in
Go
2020/07/29
posted in
Go
编辑Cargo.toml文件
[lib]
name = "speaker"
path = "src/plugins/speaker.rs"
crate-type = ["cdylib"]
[build-dependencies]
cbindgen = "*"
在build.rs中调用cbindgen生成头文件
extern crate cbindgen;
fn main() {
let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
cbindgen::Builder::new()
.with_language(cbindgen::Language::C)
.with_crate(crate_dir)
.generate()
.expect("Unable to generate C bindings.")
.write_to_file("src/plugins/speaker.h");
}
因为cbindgen默认会生成C++的头文件, 但是cgo只支持C库而不支持C++库, 所以我们需要用with_language(cbindgen::Language::C)的方式指定生成C的头文件
现在我们用Rust写一个简单的动态库
#[no_mangle]
pub extern "C" fn run() {
println!("Hello, speaker!");
}
执行cargo build命令, 会生成头文件speaker.h和动态库文件libspeaker.dylib
package main
/*
#cgo CFLAGS: -I./include
#cgo LDFLAGS: -L./lib -lspeaker
#include <speaker.h>
*/
import "C"
func main() {
C.run()
}
首先在代码中添加import "C"表示使用cgo特性
在import "C"之前的注释中使用#cgo来设置编译和链接阶段的相关参数
CFLAGS表示用于C编译器的选项, 使用-I指定头文件所在的目录
LDFLAGS告诉链接器从哪里找寻库文件(在unix系统中, ld常作为load或者loader的缩写使用), 使用-L指定库所在的目录, 使用-l指定库名