曾经有一篇关于Habr的文章,内容涉及如何从Go调用Rust代码。这篇文章不错,但是很难理解,实际上使初学者摆脱了看两种语言的渴望。这篇文章的目的不是要深入了解跨语言调用,而是要展示它可以轻松完成。
我们不会太远,并且会以一本有关学习Rust语言的书为例。该示例所做的全部工作是从头10个线程开始,在该线程中它将变量'x'增加到500万,并显示有关流结束的消息。use std::thread;
#[no_mangle]
pub extern "C" fn process() {
let handles:Vec<_> = (0..10).map(|_|{
thread::spawn(||{
let mut x = 0;
for _ in 0..5_000_000 {
x += 1
}
x
})
}).collect();
for h in handles {
println!("Thread finished with count={}",
h.join().map_err(|_| "Could not join thread!").unwrap());
}
println!("Done!");
}
您还需要通过在货物文件上添加一行来编辑货物文件板条箱类型= [“ cdylib”]
结果,将创建一个具有通过外部功能接口(FFI)调用功能的库。值得注意的是libembed.dylib是Mac OS上的一个库,在Linux上它将是libembed.so,在Windows上将是libembed.dll
谢谢:bingo347
货代[package]
name = "embed"
version = "0.1.0"
[lib]
crate-type = ["cdylib"]
通常,这是您在Rust库中要做的所有事情。书中的一个示例对此进行了更详细的描述,因此我们不再赘述。我们使用以下命令编译库:货物建造-放行
现在,我们的目标是从Go应用程序中调用此代码。我们创建一个简单的应用程序,并在项目内部添加lib文件夹,将/target/release/libembed.dylib文件复制到其中。在内部,我们使用函数名称创建文件并描述其调用签名。的lib / process.hvoid process();
在Go文件中,我们添加了这样的指令,我们的main.go看起来像这样package main
import "C"
func main() {
C.process()
}
将项目放在一起转到build -ldflags =“-r / lib” main.go
请注意ldflags参数,在这种情况下,我们要做的只是设置ELF动态链接器的路径。所有。运行程序并获取输出。
还值得一提的是,您可以将教学内容从Go程序转移到Rust库。为此,我们在Rust库中转换函数,使其采用字符串值。extern crate libc;
use std::thread;
use std::ffi::CStr;
#[no_mangle]
pub extern "C" fn process(name: *const libc::c_char) {
let buf_name = unsafe { CStr::from_ptr(name).to_bytes() };
let str_name = String::from_utf8(buf_name.to_vec()).unwrap();
let handles:Vec<_> = (0..10).map(|_|{
thread::spawn(||{
let mut x = 0;
for _ in 0..5_000_000 {
x += 1
}
x
})
}).collect();
for h in handles {
println!("{}:Thread finished with count={}\n",
str_name,
h.join().map_err(|_| "Could not join thread!\n").unwrap());
}
println!("Done!");
}
我们组装项目,再次将库复制到lib文件夹,以这种方式修改process.h文件无效过程(char *名称);
我们从Go应用程序传递了这一行(在本例中为“来自Golang的Hello”)。package main
import "C"
func main() {
C.process(C.CString("Hello from Golang !!"))
}
所有。运行程序并获取输出。