一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一次Rust重寫(xiě)基礎(chǔ)軟件的實(shí)踐

jf_wN0SrCdH ? 來(lái)源:Rust語(yǔ)言中文社區(qū) ? 2024-01-25 11:21 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

前言

受到2022年“谷歌使用Rust重寫(xiě)Android系統(tǒng)且所有Rust代碼的內(nèi)存安全漏洞為零” [1] 的啟發(fā),最近筆者懷著濃厚的興趣也順應(yīng)Rust 的潮流,嘗試著將一款C語(yǔ)言開(kāi)發(fā)的基礎(chǔ)軟件轉(zhuǎn)化為 Rust 語(yǔ)言。本文的主要目的是通過(guò)記錄此次轉(zhuǎn)化過(guò)程中遇到的比較常見(jiàn)且有意思的問(wèn)題以及解決此問(wèn)題的方法與大家一起做相關(guān)的技術(shù)交流和討論。

問(wèn)題描述

本文將記錄轉(zhuǎn)化過(guò)程中遇到的另外一個(gè)問(wèn)題。該問(wèn)題是由已經(jīng)轉(zhuǎn)化完成的 Rust 代碼使用到軟件中引入的第三方軟件包和鏈接庫(kù)所導(dǎo)致的。設(shè)想這樣一個(gè)場(chǎng)景:Rust 項(xiàng)目中完成某一個(gè)功能點(diǎn)需要用到一個(gè)或多個(gè)第三方軟件包和鏈接庫(kù)。這顯然是很常見(jiàn)的用戶場(chǎng)景,但是由于用戶環(huán)境不同,用戶安裝的第三方軟件包和鏈接庫(kù)的版本不同,使得轉(zhuǎn)化后的 Rust 代碼必須要做適當(dāng)?shù)募嫒萏幚怼?/p>

這里所說(shuō)的用戶的環(huán)境不同,可以理解為芯片指令集的平臺(tái)不同,如 Intel x86 以及國(guó)產(chǎn)的 ARM 麒麟服務(wù)器。當(dāng)然更常見(jiàn)的情形是芯片平臺(tái)相同,但是存在操作系統(tǒng)層面第三方軟件包和鏈接庫(kù)安裝的差異,如 x86 下的 Ubuntu 和 CentOS 中用戶安裝了不同版本的第三方軟件包和鏈接庫(kù)等。

事實(shí)上,即使排除所有平臺(tái)和系統(tǒng)層面的差異,由于用戶安裝了該基礎(chǔ)軟件所依賴的不同版本的第三方軟件包和鏈接庫(kù),然而這些第三方軟件包或者鏈接庫(kù)由于自身的演進(jìn)導(dǎo)致不同版本之間存在較大差異(可能實(shí)現(xiàn)相同功能的函數(shù)和函數(shù)簽名都有千差萬(wàn)別),這給我重寫(xiě)該軟件的工作帶來(lái)了一些挑戰(zhàn)。基于上述說(shuō)明,在完成重寫(xiě)該基礎(chǔ)軟件的過(guò)程中如何使得轉(zhuǎn)化后的 Rust 代碼能兼容該基礎(chǔ)軟件所依賴的主流第三方軟件包和鏈接庫(kù)則是我遇到的最大挑戰(zhàn)。需要說(shuō)明的是這里的第三方軟件包和鏈接庫(kù)可能是基于 Rust 語(yǔ)言開(kāi)發(fā)的,也可能是基于 C 語(yǔ)言開(kāi)發(fā)的。

解決方案

對(duì)于此問(wèn)題的解決方案需要使用 Rust FFI(Foreign Function Interface) [1],這基本上是沒(méi)有太大爭(zhēng)議的。因?yàn)樵诒敬诬浖貙?xiě)過(guò)程中我遇到的場(chǎng)景是:對(duì)于不同版本的鏈接庫(kù)使用哪個(gè)版本的函數(shù)取決于用戶的安裝運(yùn)行時(shí)環(huán)境,所以除了 Rust FFI,在代碼適配上我還考慮了使用 Rust features [2] 機(jī)制。

下面我簡(jiǎn)化了一下場(chǎng)景和解決方案,同時(shí)我把樣本代碼放到了我的 github [3] 里,歡迎大家一起交流。如樣本代碼所示,my-rust-bin 文件夾中的一段業(yè)務(wù)代碼需要調(diào)用到靜態(tài)鏈接庫(kù) my_rust_lib 中的函數(shù),該鏈接庫(kù)有兩個(gè)版本 v1(在文件夾 my-rust-lib-v1 中) 和 v2(在文件夾 my-rust-lib-v2 中), 且不同版本的庫(kù)其函數(shù)不一樣。

my-rust-lib-v1 對(duì)應(yīng)的業(yè)務(wù)函數(shù)為:pub fn my_rust_lib_v1(left: usize, right: usize) -> usize

my-rust-lib-v2 對(duì)應(yīng)的業(yè)務(wù)函數(shù)為:pub fn my_rust_lib_v2(left: usize, right: usize) -> usize

另外一個(gè) lib 文件夾的目的其實(shí)是為了模擬用戶本地安裝的鏈接庫(kù)??梢苑謩e編譯不同版本的靜態(tài)鏈接庫(kù),然后把生成的庫(kù)文件(在本例中是)libmy_rust_lib.a, 然后把不同版本的庫(kù)文件拷貝到此文件夾下,以此來(lái)模擬用戶環(huán)境中安裝的不同版本的鏈接庫(kù)。解決方案中的關(guān)鍵點(diǎn)在于 my-rust-bin 中,

首先在 my-rust-bin 的 Cargo.toml 中有定義對(duì)應(yīng)的 features,如下所示:

[features]
v1=[]
v2=[]

其次在 my-rust-bin 的 src/main.rs 下的代碼如下:

#[cfg(feature="v1")]
modbindingmylib{
extern"C"{
pubfnmy_rust_lib_v1(left:usize,right:usize)->usize;
}
}

#[cfg(feature="v2")]
modbindingmylib{
extern"C"{
pubfnmy_rust_lib_v2(left:usize,right:usize)->usize;
}
}

#[cfg(not(any(feature="v1",feature="v2")))]
compile_error!("Pleasespecifyeither'v1'or'v2'feature");

pubfnmy_rust_lib(left:usize,right:usize)->usize{
#[cfg(feature="v1")]
unsafe{
returnbindingmylib::my_rust_lib_v1(left,right);
}

#[cfg(feature="v2")]
unsafe{
returnbindingmylib::my_rust_lib_v2(left,right);
}
}

fnmain(){
letr_value:usize=my_rust_lib(3,5);
println!("Thereturnvalueofmy_rust_libis[{}]",r_value);
}

現(xiàn)在我來(lái)解讀一下這段代碼。代碼先分別定義一個(gè)相同的模塊 bindingmylib,然后根據(jù) features 分別引入的依賴,使用的不同的靜態(tài)鏈接庫(kù)函數(shù)(my_rust_lib_v1 和 my_rust_lib_v2), 同時(shí)通過(guò) compile_error! 定義一個(gè)沒(méi)有設(shè)置 v1 和 v2 features 的編譯錯(cuò)誤(防止編譯時(shí)忘記設(shè)置 features選項(xiàng),下面在編譯環(huán)節(jié)的時(shí)候有用)。最后將兩個(gè)有差異的函數(shù)統(tǒng)一為函數(shù) my_rust_lib,并在該函數(shù)中根據(jù) features 定義分別調(diào)用不同的函數(shù)并返回相應(yīng)的值。

最后是在 my-rust-bin 中編譯二進(jìn)制文件:

編譯并運(yùn)行 v1 的二進(jìn)制文件

#編譯v1版本的my-rust-bin
$cdmy-rust-bin
$cargobuild--features="v1"

#運(yùn)行v1版本的my-rust-bin
$target/debug/my-rust-bin
my_rust_lib_v1:8
Thereturnvalueofmy_rust_libis[8]

編譯并運(yùn)行 v2 的二進(jìn)制文件

#編譯v2版本的my-rust-bin
$cdmy-rust-bin
$cargobuild--features="v2"

#運(yùn)行v2版本的my-rust-bin
$target/debug/my-rust-bin
my_rust_lib_v2:8
Thereturnvalueofmy_rust_libis[8]

備注:如果編譯的時(shí)候沒(méi)有設(shè)置 --features 則會(huì)有如下輸出:

$cargobuild
error:Pleasespecifyeither'v1'or'v2'feature
-->src/main.rs1
|
16|compile_error!("Pleasespecifyeither'v1'or'v2'feature");
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

至此,用戶在編譯好該基礎(chǔ)軟件之后,就可以無(wú)感知的通過(guò)統(tǒng)一的函數(shù)入口調(diào)用不同版本的相同鏈接庫(kù)中的不同函數(shù)了。

總結(jié)

本文主要是在簡(jiǎn)化了問(wèn)題的實(shí)際場(chǎng)景以后,解決不同版本的同一軟件包或者鏈接庫(kù)中,函數(shù)及其函數(shù)簽名不同導(dǎo)致的調(diào)用問(wèn)題。之所以說(shuō)簡(jiǎn)化,主要是本文所描述的場(chǎng)景中,my-rust-bin 和其依賴的外部鏈接庫(kù)均是 Rust 編寫(xiě)。而在我的實(shí)際場(chǎng)景中則會(huì)更復(fù)雜一些,存在著 Rust 代碼依賴 C 編寫(xiě)的外部鏈接庫(kù),同時(shí)存在混合的原來(lái) C 代碼部分依賴新改寫(xiě)的 Rust 外部鏈接庫(kù)的情況。但是無(wú)論哪種情況,萬(wàn)變不離其宗,我們都可以從這種最簡(jiǎn)單的場(chǎng)景出發(fā)去解決遇到的問(wèn)題。

關(guān)于作者

張懷龍?jiān)吐氂诎柨ㄌ乩视?,百度,IBM等企業(yè)從事云計(jì)算研發(fā)相關(guān)的工作。目前就職于 Intel 中國(guó),擔(dān)任云原生開(kāi)發(fā)工程師并致力于云原生、服務(wù)網(wǎng)格等技術(shù)領(lǐng)域研究實(shí)踐,也是Istio 的maintainer的開(kāi)發(fā)者。曾多次在 KubeCon、ServiceMeshCon、IstioCon、GOTC 和 InfoQ/QCon 等大會(huì)上發(fā)表演講。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 操作系統(tǒng)
    +關(guān)注

    關(guān)注

    37

    文章

    7122

    瀏覽量

    125258
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7630

    瀏覽量

    140970
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4893

    瀏覽量

    70441
  • Rust
    +關(guān)注

    關(guān)注

    1

    文章

    233

    瀏覽量

    7015

原文標(biāo)題:一次Rust重寫(xiě)基礎(chǔ)軟件的實(shí)踐(二)

文章出處:【微信號(hào):Rust語(yǔ)言中文社區(qū),微信公眾號(hào):Rust語(yǔ)言中文社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Rust GUI實(shí)踐Rust-Qt模塊

    Rust-Qt 是 Rust 語(yǔ)言的個(gè) Qt 綁定庫(kù),它允許 Rust 開(kāi)發(fā)者使用 Qt 框架來(lái)創(chuàng)建跨平臺(tái)的圖形界面應(yīng)用程序。Qt 是個(gè)
    的頭像 發(fā)表于 09-30 16:43 ?1980次閱讀

    進(jìn)步降低冰箱旋轉(zhuǎn)式壓縮機(jī)噪聲的一次實(shí)踐

    進(jìn)步降低冰箱旋轉(zhuǎn)式壓縮機(jī)噪聲的一次實(shí)踐
    發(fā)表于 05-20 15:19 ?646次下載

    循環(huán)充放電一次就是少一次壽命嗎?

    循環(huán)充放電一次就是少一次壽命嗎?循環(huán)就是使用,我們是在使用電池,關(guān)心的是使用的時(shí)間,為了衡量充電電池的到底可以使用多長(zhǎng)時(shí)間這樣個(gè)性能,就規(guī)定了循環(huán)
    發(fā)表于 09-07 02:06 ?2343次閱讀

    一次電池為什么不能被充電?

    一次電池為什么不能被充電? 一次電池不能被充電再生是構(gòu)成一次電池體系的本性所決定的,因?yàn)?b class='flag-5'>一次電池的電極反應(yīng)不可逆,也就是說(shuō),放電后的放電產(chǎn)
    發(fā)表于 10-28 15:29 ?5988次閱讀

    循環(huán)充放電一次就是少一次壽命嗎?

    循環(huán)充放電一次就是少一次壽命嗎?     循環(huán)就是使用,我們是在使用電池,關(guān)心的是使
    發(fā)表于 11-11 13:59 ?947次閱讀

    電池循環(huán)充放電一次就是少一次壽命嗎?

    電池循環(huán)充放電一次就是少一次壽命嗎? 循環(huán)就是使用,我們是在使用電池,關(guān)心的是使用的時(shí)間,為了衡量充電電池
    發(fā)表于 09-06 11:05 ?3705次閱讀

    微軟開(kāi)發(fā)基于Rust的新編程語(yǔ)言,將很快開(kāi)源

    使用Rust重寫(xiě)各種產(chǎn)品,因?yàn)樵谶^(guò)去的十年里,微軟70%以上的安全補(bǔ)丁都提供了與內(nèi)存相關(guān)的錯(cuò)誤,而Rust正是解決這個(gè)問(wèn)題的良藥。 而根據(jù)ZDNet的報(bào)導(dǎo),近日在一次演講中,談到微軟為
    的頭像 發(fā)表于 12-03 10:36 ?4082次閱讀

    微軟正在研發(fā)基于Rust新的安全編程語(yǔ)言

    為提高 Windows 10 的安全性,微軟研究人員 Matthew Parkinson 在本周的一次演講中披露:微軟正基于 Rust 開(kāi)發(fā)新的安全編程語(yǔ)言。
    的頭像 發(fā)表于 12-06 16:36 ?3418次閱讀

    電氣一次識(shí)圖基礎(chǔ)

    電氣一次識(shí)圖基礎(chǔ)
    的頭像 發(fā)表于 11-12 11:24 ?2318次閱讀

    Cloudflare用Rust重寫(xiě)Nginx C模塊,構(gòu)建沒(méi)有Nginx的未來(lái)

    近日,Cloudflare 工程師介紹了如何使用 Rust 重寫(xiě)基于 C 語(yǔ)言的 Nginx 模塊。Cloudflare 工程師在博客寫(xiě)道,他們用 Rust 為 Cloudflare 基礎(chǔ)設(shè)施中最
    的頭像 發(fā)表于 03-08 09:36 ?977次閱讀

    Rust重寫(xiě)的LSP:KCL IDE 插件的功能介紹與設(shè)計(jì)解析

    在這次更新中,我們發(fā)布了全新的 KCL VS Code 插件,并且用 Rust 重寫(xiě)了 LSP 的 Server 端。我們提供了 IDE 中常用的代碼輔助功能,如高亮、跳轉(zhuǎn)、補(bǔ)全、Outline、懸停、錯(cuò)誤提示等。
    的頭像 發(fā)表于 05-11 09:39 ?1305次閱讀
    <b class='flag-5'>Rust</b><b class='flag-5'>重寫(xiě)</b>的LSP:KCL IDE 插件的功能介紹與設(shè)計(jì)解析

    Windows 11初嘗Rust,36000行內(nèi)核代碼已重寫(xiě)!

    更早些時(shí)候,微軟用 Rust 重寫(xiě)了 DirectWrite Core 庫(kù)的概念驗(yàn)證,它是 Windows 的 DWrite 引擎的 Windows App SDK 實(shí)現(xiàn),用于文本分析、布局和渲染
    的頭像 發(fā)表于 05-19 16:39 ?1247次閱讀
    Windows 11初嘗<b class='flag-5'>Rust</b>,36000行內(nèi)核代碼已<b class='flag-5'>重寫(xiě)</b>!

    一次調(diào)頻和二調(diào)頻的概念 一次調(diào)頻可以實(shí)現(xiàn)無(wú)差調(diào)節(jié)?

    一次調(diào)頻和二調(diào)頻的概念 一次調(diào)頻可以實(shí)現(xiàn)無(wú)差調(diào)節(jié)? 、一次調(diào)頻和二調(diào)頻的概念 1.
    的頭像 發(fā)表于 10-17 16:15 ?1.1w次閱讀

    Rust重寫(xiě)基礎(chǔ)軟件實(shí)踐代碼

    在項(xiàng)目轉(zhuǎn)化過(guò)程中我遇到了個(gè)與 CAS (Compare and Swap) [2] 操作實(shí)現(xiàn)相關(guān)的問(wèn)題,在計(jì)算機(jī)科學(xué)中CAS 是多線程/協(xié)程中用于實(shí)現(xiàn)同步的原子指令。
    的頭像 發(fā)表于 01-19 10:05 ?768次閱讀

    JavaScript與Rust和WebAssembly集成

    偶然一次機(jī)會(huì),接觸了Rust的代碼。當(dāng)時(shí)想給團(tuán)隊(duì)小伙伴做演示,發(fā)現(xiàn)自己并不能在移動(dòng)端按照文檔生成演示demo。我就想,要是Rust代碼能轉(zhuǎn)化成JavaScript就好了。結(jié)果搜,還真
    的頭像 發(fā)表于 01-24 15:43 ?414次閱讀
    JavaScript與<b class='flag-5'>Rust</b>和WebAssembly集成