欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go調(diào)用Rust方法及外部函數(shù)接口前置

 更新時(shí)間:2022年06月13日 16:22:30   作者:張晉濤  
這篇文章主要為大家介紹了Go調(diào)用Rust方法及外部函數(shù)接口前置示例實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

近期 Rust 社區(qū)/團(tuán)隊(duì)有些變動(dòng),所以再一次將 Rust 拉到大多數(shù)人眼前。

我最近看到很多小伙伴說(shuō)的話:

  • Rust 還值得學(xué)嗎?社區(qū)是不是不穩(wěn)定呀
  • Rust 和 Go 哪個(gè)好?
  • Rust 還值得學(xué)嗎?

這些問(wèn)題如果有人來(lái)問(wèn)我,那我的回答是:

小孩子才做選擇,我都要!

當(dāng)然,關(guān)于 Rust 和 Go 的問(wèn)題也不算新,比如之前的一條推文:

我在本篇中就來(lái)介紹下如何用 Go 調(diào)用 Rust。

當(dāng)然,這篇中我基本上不會(huì)去比較 Go 和 Rust 的功能,或者這種方式的性能之類的,Just for Fun

FFI 和 Binding

FFI (Foreign Function Interface) 翻譯過(guò)來(lái)叫做外部函數(shù)接口(為了比較簡(jiǎn)單,下文中都將使用 FFI 指代)。最早來(lái)自于 Common Lisp 的規(guī)范,這是在 wiki 上寫的,我并沒有去考證。 不過(guò)我所使用過(guò)的絕大多數(shù)語(yǔ)言中都有 FFI 的概念/術(shù)語(yǔ)存在,比如:Python、Ruby, Haskell、Go、Rust、LuaJIT 等。

FFI 的作用簡(jiǎn)單來(lái)說(shuō)就是允許一種語(yǔ)言去調(diào)用另一種語(yǔ)言,有時(shí)候我們也會(huì)用 Binding 來(lái)表示類似的能力。

在不同的語(yǔ)言中會(huì)有不同的實(shí)現(xiàn),比如在 Go 中的 cgo , Python 中的 ctypes , Haskell 中的 CAPI (之前還有一個(gè) ccall)等。 我個(gè)人感覺 Haskell 中用 FFI 相比其他語(yǔ)言要更簡(jiǎn)單&方便的多,不過(guò)這不是本篇的重點(diǎn)就不展開了。

在本文中,對(duì)于 Go 和 Rust 而言,它們的 FFI 需要與 C 語(yǔ)言對(duì)象進(jìn)行通信,而這部分其實(shí)是由操作系統(tǒng)根據(jù) API 中的調(diào)用約定來(lái)完成的。

我們來(lái)進(jìn)入正題。

準(zhǔn)備 Rust 示例程序

Rust 的安裝和 Cargo 工具的基本使用,這里就不介紹了。大家可以去 Rust 的官網(wǎng)進(jìn)行了解。

用 Cargo 創(chuàng)建項(xiàng)目

我們先準(zhǔn)備一個(gè)目錄用來(lái)放本次示例的代碼。(我創(chuàng)建的目錄叫做 go-rust )

然后使用 Rust 的 Cargo 工具創(chuàng)建一個(gè)名叫 rustdemo 的項(xiàng)目,這里由于我增加了 --lib 的選項(xiàng),使用其內(nèi)置的 library 模板。

?  go-rust git:(master) ? mkdir lib && cd lib
?  go-rust git:(master) ? cargo new --lib rustdemo
     Created library `rustdemo` package
?  go-rust git:(master) ? tree rustdemo 
rustdemo
├── Cargo.toml
└── src
    └── lib.rs
1 directory, 2 files

準(zhǔn)備 Rust 代碼

extern crate libc;
use std::ffi::{CStr, CString};
#[no_mangle] 
pub extern "C" fn rustdemo(name: *const libc::c_char) -> *const libc::c_char {
    let cstr_name = unsafe { CStr::from_ptr(name) };
    let mut str_name = cstr_name.to_str().unwrap().to_string();
    println!("Rust get Input:  \"{}\"", str_name);
    let r_string: &str = " Rust say: Hello Go ";
    str_name.push_str(r_string);
    CString::new(str_name).unwrap().into_raw()
}

代碼比較簡(jiǎn)單,Rust 暴露出來(lái)的函數(shù)名叫做 rustdemo ,接收一個(gè)外部的參數(shù),并將其打印出來(lái)。之后從 Rust 這邊再設(shè)置一個(gè)字符串。

CString::new(str_name).unwrap().into_raw() 被轉(zhuǎn)換為原始指針,以便之后由 C 語(yǔ)言處理。

編譯 Rust 代碼

我們需要修改下 Cargo.toml 文件以便進(jìn)行編譯。注意,這里我們?cè)黾恿?crate-type = ["cdylib"] 和 libc 。

[package]
name = "rustdemo"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
libc = "0.2"

然后進(jìn)行編譯

?  rustdemo git:(master) ? cargo build --release
   Compiling rustdemo v0.1.0 (/home/tao/go/src/github.com/tao12345666333/go-rust/lib/rustdemo)
    Finished release [optimized] target(s) in 0.22s

查看生成的文件,這是一個(gè) .so 文件(這是因?yàn)槲以?Linux 環(huán)境下,你如果在其他系統(tǒng)環(huán)境下會(huì)不同)

?  rustdemo git:(master) ? ls target/release/librustdemo.so 
target/release/librustdemo.so

準(zhǔn)備 Go 代碼

Go 環(huán)境的安裝之類的這里也不再贅述了,繼續(xù)在我們的 go-rust 目錄操作即可。

編寫 main.go

package main
/*
#cgo LDFLAGS: -L./lib -lrustdemo
#include <stdlib.h>
#include "./lib/rustdemo.h"
*/
import "C"
import (
	"fmt"
	"unsafe"
)
func main() {
	s := "Go say: Hello Rust"
	input := C.CString(s)
	defer C.free(unsafe.Pointer(input))
	o := C.rustdemo(input)
	output := C.GoString(o)
	fmt.Printf("%s\n", output)
}

在這里我們使用了 cgo ,在 import "C" 之前的注釋內(nèi)容是一種特殊的語(yǔ)法,這里是正常的 C 代碼,其中需要聲明使用到的頭文件之類的。

下面的代碼很簡(jiǎn)單,定義了一個(gè)字符串,傳遞給 rustdemo 函數(shù),然后打印 C 處理后的字符串。

同時(shí),為了能夠讓 Go 程序能正常調(diào)用 Rust 函數(shù),這里我們還需要聲明其頭文件,在 lib/rustdemo.h 中寫入如下內(nèi)容:

char* rustdemo(char *name);

編譯代碼

在 Go 編譯的時(shí)候,我們需要開啟 CGO (默認(rèn)都是開啟的),同時(shí)需要鏈接到 Rust 構(gòu)建出來(lái)的 rustdemo.so 文件,所以我們將該文件和它的頭文件放到 lib 目錄下。

?  go-rust git:(master) ? cp lib/rustdemo/target/release/librustdemo.so lib

所以完整的目錄結(jié)構(gòu)就是:

?  go-rust git:(master) ? tree -L 2 .
.
├── go.mod
├── lib
│   ├── librustdemo.so
│   ├── rustdemo
│   └── rustdemo.h
└── main.go
2 directories, 5 files

編譯:

?  go-rust git:(master) ? go build -o go-rust  -ldflags="-r ./lib" main.go
?  go-rust git:(master) ? ./go-rust 
Rust get Input:  "Go say: Hello Rust"
Go say: Hello Rust Rust say: Hello Go

可以看到,第一行的輸出是由 Go 傳入了 Rust , 第二行中則是從 Rust 再傳回 Go 的了。符合我們的預(yù)期。

總結(jié)

本篇介紹了如何使用 Go 與 Rust 進(jìn)行結(jié)合,介紹了其前置關(guān)于 FFI 相關(guān)的知識(shí),后續(xù)通過(guò)一個(gè)小的實(shí)踐演示了其完整過(guò)程。 感興趣的小伙伴可以自行實(shí)踐下,更多關(guān)于Go調(diào)用Rust外部函數(shù)接口前置的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入了解Rust中trait的使用

    深入了解Rust中trait的使用

    先前我們提到過(guò)?trait,那么Rust中的trait?是啥呢?本文將通過(guò)一些示例為大家詳細(xì)講講Rust中trait的使用,感興趣的小伙伴可以了解一下
    2022-11-11
  • C++的替代:微軟如何使用rust?

    C++的替代:微軟如何使用rust?

    這篇文章主要介紹了微軟如何使用rust的,幫助大家了解c++和rust這兩門編程語(yǔ)言的聯(lián)系與區(qū)別,感興趣的朋友可以了解下
    2020-09-09
  • 關(guān)于rust的模塊引入問(wèn)題

    關(guān)于rust的模塊引入問(wèn)題

    Rust 語(yǔ)言是一種高效、可靠的通用高級(jí)語(yǔ)言,它的執(zhí)行效率也是令人稱贊的,是一種少有的兼顧開發(fā)效率和執(zhí)行效率的語(yǔ)言,這篇文章主要介紹了rust的模塊引入相關(guān)知識(shí),需要的朋友可以參考下
    2022-10-10
  • Rust使用Channel實(shí)現(xiàn)跨線程傳遞數(shù)據(jù)

    Rust使用Channel實(shí)現(xiàn)跨線程傳遞數(shù)據(jù)

    消息傳遞是一種很流行且能保證安全并發(fā)的技術(shù),Rust也提供了一種基于消息傳遞的并發(fā)方式,在rust里使用標(biāo)準(zhǔn)庫(kù)提供的Channel來(lái)實(shí)現(xiàn),下面我們就來(lái)學(xué)習(xí)一下如何使用Channel實(shí)現(xiàn)跨線程傳遞數(shù)據(jù)吧
    2023-12-12
  • Rust?連接?PostgreSQL?數(shù)據(jù)庫(kù)的詳細(xì)過(guò)程

    Rust?連接?PostgreSQL?數(shù)據(jù)庫(kù)的詳細(xì)過(guò)程

    這篇文章主要介紹了Rust?連接?PostgreSQL?數(shù)據(jù)庫(kù)的完整代碼,本文圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-01-01
  • rust流程控制的具體使用

    rust流程控制的具體使用

    在Rust中,控制流包括條件語(yǔ)句、循環(huán)和匹配模式等,用于實(shí)現(xiàn)程序的邏輯和流程控制,本文就來(lái)詳細(xì)的介紹一下,感興趣的可以了解一下
    2023-12-12
  • Rust中FFI編程知識(shí)點(diǎn)整理總結(jié)(推薦)

    Rust中FFI編程知識(shí)點(diǎn)整理總結(jié)(推薦)

    這篇文章主要介紹了Rust中FFI編程知識(shí)點(diǎn)整理總結(jié),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • 詳解Rust Substrate框架中的Runtime

    詳解Rust Substrate框架中的Runtime

    ubstrate是一個(gè)區(qū)塊鏈開發(fā)框架,它提供了一系列模塊化和可擴(kuò)展的組件,可以幫助開發(fā)人員快速構(gòu)建自定義區(qū)塊鏈。 Runtime是Substrate區(qū)塊鏈的核心部分,文中有詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-05-05
  • C和Java沒那么香了,Serverless時(shí)代Rust即將稱王?

    C和Java沒那么香了,Serverless時(shí)代Rust即將稱王?

    Serverless Computing,即”無(wú)服務(wù)器計(jì)算”,其實(shí)這一概念在剛剛提出的時(shí)候并沒有獲得太多的關(guān)注,直到2014年AWS Lambda這一里程碑式的產(chǎn)品出現(xiàn)。Serverless算是正式走進(jìn)了云計(jì)算的舞臺(tái)
    2021-06-06
  • 詳解Rust語(yǔ)言中anyhow的使用

    詳解Rust語(yǔ)言中anyhow的使用

    anyhow是一個(gè)Rust庫(kù),用于簡(jiǎn)化錯(cuò)誤處理和提供更好的錯(cuò)誤報(bào)告,這個(gè)庫(kù)適合用于應(yīng)用程序,而不是用于創(chuàng)建庫(kù),因?yàn)樗峁┝艘粋€(gè)非結(jié)構(gòu)化的,方便使用的錯(cuò)誤類型,本文就給大家講講Rust語(yǔ)言中anyhow的使用,需要的朋友可以參考下
    2023-08-08

最新評(píng)論