女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

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

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

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

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

jf_wN0SrCdH ? 來源:Rust語言中文社區(qū) ? 2024-01-25 11:21 ? 次閱讀

前言

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

問題描述

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

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

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

解決方案

對于此問題的解決方案需要使用 Rust FFI(Foreign Function Interface) [1],這基本上是沒有太大爭議的。因為在本次軟件重寫過程中我遇到的場景是:對于不同版本的鏈接庫使用哪個版本的函數(shù)取決于用戶的安裝運行時環(huán)境,所以除了 Rust FFI,在代碼適配上我還考慮了使用 Rust features [2] 機制。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

總結(jié)

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

關(guān)于作者

張懷龍曾就職于阿爾卡特朗訊,百度,IBM等企業(yè)從事云計算研發(fā)相關(guān)的工作。目前就職于 Intel 中國,擔(dān)任云原生開發(fā)工程師并致力于云原生、服務(wù)網(wǎng)格等技術(shù)領(lǐng)域研究實踐,也是Istio 的maintainer的開發(fā)者。曾多次在 KubeCon、ServiceMeshCon、IstioCon、GOTC 和 InfoQ/QCon 等大會上發(fā)表演講。

審核編輯:湯梓紅

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

    關(guān)注

    37

    文章

    7095

    瀏覽量

    124965
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7630

    瀏覽量

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

    關(guān)注

    30

    文章

    4887

    瀏覽量

    70264
  • Rust
    +關(guān)注

    關(guān)注

    1

    文章

    233

    瀏覽量

    6962

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

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

收藏 人收藏

    評論

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

    Rust GUI實踐Rust-Qt模塊

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Cloudflare用Rust重寫Nginx C模塊,構(gòu)建沒有Nginx的未來

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

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

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

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

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

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

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

    Rust重寫基礎(chǔ)軟件實踐代碼

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

    JavaScript與Rust和WebAssembly集成

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