在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
指定库名