中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

html制作網(wǎng)站的步驟網(wǎng)絡(luò)服務(wù)包括

html制作網(wǎng)站的步驟,網(wǎng)絡(luò)服務(wù)包括,網(wǎng)站制作 牛商網(wǎng),做網(wǎng)站表格單邊框標(biāo)記本示例演示了一個(gè)調(diào)用blobstore服務(wù)的C客戶(hù)端的Rust應(yīng)用程序。事實(shí)上,我們會(huì)看到兩個(gè)方向的調(diào)用:Rust到C以及C到Rust。對(duì)于您自己的用例,您可能只需要其中一個(gè)方向。 示例中涉及的所有代碼都顯示在此頁(yè)面上,但它也以可運(yùn)行的形式提…

本示例演示了一個(gè)調(diào)用blobstore服務(wù)的C++客戶(hù)端的Rust應(yīng)用程序。事實(shí)上,我們會(huì)看到兩個(gè)方向的調(diào)用:Rust到C++以及C++到Rust。對(duì)于您自己的用例,您可能只需要其中一個(gè)方向。
示例中涉及的所有代碼都顯示在此頁(yè)面上,但它也以可運(yùn)行的形式提供在demo目錄中https://github.com/dtolnay/cxx.要直接嘗試,請(qǐng)從該目錄運(yùn)行cargo run。
共享結(jié)構(gòu)、不透明類(lèi)型和函數(shù)已經(jīng)在上一篇文章中敘述,不清楚的可以先去看一下。

一、創(chuàng)建項(xiàng)目

我們?cè)诿钚兄袆?chuàng)建一個(gè)空白的Cargo項(xiàng)目:
cargo new cxx-demo
編輯Cargo.toml文件,添加對(duì)cxx的依賴(lài):

[dependencies]
cxx = "1.0"

二、定義語(yǔ)言邊界

CXX依賴(lài)于對(duì)每種語(yǔ)言向另一種語(yǔ)言公開(kāi)的函數(shù)簽名的描述。您可以在Rust模塊中使用extern塊提供此描述,該模塊用#[cxx::bridge]屬性宏注釋。
我們?cè)陧?xiàng)目的main.rs文件的頂部添加該內(nèi)容:

#[cxx::bridge]
mod ffi {
}

該內(nèi)容將是FFI邊界雙方需要達(dá)成一致的所有內(nèi)容。

三、從Rust調(diào)用C++函數(shù)

讓我們獲取一個(gè)C++blobstore客戶(hù)端的實(shí)例,一個(gè)在C++中定義的類(lèi)blobstore client。
我們將把BlobstreClient視為CXX分類(lèi)中的不透明類(lèi)型,這樣Rust就不需要對(duì)其實(shí)現(xiàn)做出任何假設(shè),甚至不需要對(duì)它的大小或?qū)R方式做出任何假設(shè)。一般來(lái)說(shuō),C++類(lèi)型可能有一個(gè)與Rust的move語(yǔ)義不兼容的move構(gòu)造函數(shù),或者可能包含Rust的借用系統(tǒng)無(wú)法建模的內(nèi)部引用。盡管有其他選擇,但在FFI邊界上不關(guān)心任何此類(lèi)事情的最簡(jiǎn)單方法是將其視為不透明,不需要了解類(lèi)型。
不透明類(lèi)型只能在間接后面操作,如引用&、Rust Box或UniquePtr(std::unique_ptr的Rust綁定)。我們將添加一個(gè)函數(shù),通過(guò)該函數(shù),C++可以向Rust返回std::unique_ptr。

// src/main.rs#[cxx::bridge]
mod ffi {unsafe extern "C++" {include!("cxx-demo/include/blobstore.h");type BlobstoreClient;fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;}
}fn main() {let client = ffi::new_blobstore_client();
}

即使CXX自動(dòng)執(zhí)行靜態(tài)斷言,確保簽名與C++中聲明的完全匹配,我們?nèi)匀恍枰_保鍵入的簽名是準(zhǔn)確的。比如new_blobstore_client函數(shù)如果會(huì)發(fā)生意外(如內(nèi)存錯(cuò)誤)必須用unsafe標(biāo)記。這次是在一個(gè)安全的extern“C++”塊中,因?yàn)槌绦騿T不再需要對(duì)簽名進(jìn)行任何安全聲明。

四、添加C++代碼

在CXX與Cargo的集成中,默認(rèn)情況下,所有#include路徑都以單元包(crate)名稱(chēng)開(kāi)頭。這就是為什么我們看到 include!(“cxx-demowj/include/blobstore.h”) ——我們將把C++頭文件放在Rust單元包內(nèi)的相對(duì)路徑include/blostore.h處。如果根據(jù)Cargo.toml中的name字段,你的crate的名稱(chēng)不是cxx-demo,那么在本教程中,你需要在所有地方使用這個(gè)名稱(chēng)來(lái)代替cxx-demo。

// include/blobstore.h#pragma once
#include <memory>class BlobstoreClient {
public:BlobstoreClient();
};std::unique_ptr<BlobstoreClient> new_blobstore_client();// src/blobstore.cc#include "cxx-demo/include/blobstore.h"BlobstoreClient::BlobstoreClient() {}std::unique_ptr<BlobstoreClient> new_blobstore_client() {return std::unique_ptr<BlobstoreClient>(new BlobstoreClient());
}

使用std::make_unique也可以,只要你將std(“c++14”)傳遞給c++編譯器,如稍后所述。
include/和src/中的位置并不重要;只要在整個(gè)項(xiàng)目中使用正確的路徑,就可以將C++代碼放置在單元包中的任何其他位置。
請(qǐng)注意,CXX不會(huì)查看這些文件中的任何一個(gè)。你可以自由地在這里放任意的C++代碼, #include你自主的庫(kù)等等。CXX庫(kù)所做的就是針對(duì)您在頭文件中提供的內(nèi)容發(fā)出靜態(tài)斷言。

五、用Cargo編譯C++代碼

Cargo有一個(gè)適合編譯非Rust代碼的構(gòu)建腳本功能。
我們需要在Cargo.toml中引入對(duì)CXX的C++代碼生成器的新的構(gòu)建時(shí)依賴(lài):

# Cargo.toml[dependencies]
cxx = "1.0"[build-dependencies]
cxx-build = "1.0"

然后在Cargo.toml旁邊添加一個(gè)build.rs構(gòu)建腳本,以運(yùn)行cxx構(gòu)建代碼生成器和C++編譯器。相關(guān)參數(shù)是包含cxx::bridge語(yǔ)言邊界定義的Rust源文件的路徑,以及在Rust crate構(gòu)建過(guò)程中要編譯的任何其他C++源文件的道路。

// build.rsfn main() {cxx_build::bridge("src/main.rs").file("src/blobstore.cc").compile("cxx-demo");println!("cargo:rerun-if-changed=src/main.rs");println!("cargo:rerun-if-changed=src/blobstore.cc");println!("cargo:rerun-if-changed=include/blobstore.h");
}

他的build.rs也是您設(shè)置C++編譯器標(biāo)志的地方,例如,如果您想從C++14訪(fǎng)問(wèn)std::make_unique。

 cxx_build::bridge("src/main.rs").file("src/blobstore.cc").std("c++14").compile("cxx-demo");

盡管還沒(méi)有做任何有用的事情,該項(xiàng)目現(xiàn)在應(yīng)該能夠成功構(gòu)建和運(yùn)行。命令行輸入命令如下:

<cxx-demo路徑提示符>  cargo runCompiling cxx-demo v0.1.0Finished dev [unoptimized + debuginfo] target(s) in 0.34sRunning `target/debug/cxx-demo`<cxx-demo路徑提示符>

六、從C++調(diào)用Rust函數(shù)

我們的C++blobstore支持不連續(xù)緩沖區(qū)上傳的put操作。例如,我們可能正在上傳一個(gè)循環(huán)緩沖區(qū)的快照,該緩沖區(qū)往往由2個(gè)部分組成,或者由于其他原因(如繩索數(shù)據(jù)結(jié)構(gòu))而分散在內(nèi)存中的文件片段。
我們將通過(guò)在連續(xù)的借用塊上傳遞迭代器來(lái)表達(dá)這一點(diǎn)。這與廣泛使用的字節(jié)箱的Buf特性的API非常相似。在put過(guò)程中,我們將讓C++回調(diào)到Rust中,以獲取上傳的連續(xù)塊(所有塊都沒(méi)有在語(yǔ)言邊界上進(jìn)行復(fù)制或分配)。實(shí)際上,C++客戶(hù)端可能包含一些復(fù)雜的塊批處理或并行上傳,所有這些都與之相關(guān)。

// src/main.rs#[cxx::bridge]
mod ffi {extern "Rust" {type MultiBuf;fn next_chunk(buf: &mut MultiBuf) -> &[u8];}unsafe extern "C++" {include!("cxx-demo/include/blobstore.h");type BlobstoreClient;fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;fn put(&self, parts: &mut MultiBuf) -> u64;}
}

任何具有self參數(shù)的簽名(等同C++的this)都被認(rèn)為是一個(gè)方法/非靜態(tài)成員函數(shù)。如果周?chē)膃xtern塊中只有一個(gè)類(lèi)型,則它將是該類(lèi)型的方法。如果有多個(gè)類(lèi)型,您可以通過(guò)在參數(shù)列表中編寫(xiě)self:&BlostreClient來(lái)區(qū)分方法屬于哪一個(gè)。
像往常一樣,現(xiàn)在我們需要提供extern“Rust”塊聲明的所有內(nèi)容的Rust定義,以及extern“C++”塊宣布的新簽名的C++定義。

// src/main.rs// An iterator over contiguous chunks of a discontiguous file object. Toy
// implementation uses a Vec<Vec<u8>> but in reality this might be iterating
// over some more complex Rust data structure like a rope, or maybe loading
// chunks lazily from somewhere.
pub struct MultiBuf {chunks: Vec<Vec<u8>>,pos: usize,
}pub fn next_chunk(buf: &mut MultiBuf) -> &[u8] {let next = buf.chunks.get(buf.pos);buf.pos += 1;next.map_or(&[], Vec::as_slice)
}
// include/blobstore.hstruct MultiBuf;class BlobstoreClient {
public:BlobstoreClient();uint64_t put(MultiBuf &buf) const;
};

在blobstre.cc中,我們可以調(diào)用Rust next_chunk函數(shù),該函數(shù)通過(guò)CXX代碼生成器生成的頭部文件main.rs.h暴露給C++。在CXX的Cargo集成中,這個(gè)生成的頭文件有一個(gè)包含crate名稱(chēng)、crate中Rust源文件的相對(duì)路徑和.rs.h擴(kuò)展名的路徑。

// src/blobstore.cc#include "cxx-demo/include/blobstore.h"
#include "cxx-demo/src/main.rs.h"
#include <functional>
#include <string>// Upload a new blob and return a blobid that serves as a handle to the blob.
uint64_t BlobstoreClient::put(MultiBuf &buf) const {// Traverse the caller's chunk iterator.std::string contents;while (true) {auto chunk = next_chunk(buf);if (chunk.size() == 0) {break;}contents.append(reinterpret_cast<const char *>(chunk.data()), chunk.size());}// Pretend we did something useful to persist the data.auto blobid = std::hash<std::string>{}(contents);return blobid;
}

現(xiàn)在可以使用了

// src/main.rsfn main() {let client = ffi::new_blobstore_client();// Upload a blob.let chunks = vec![b"fearless".to_vec(), b"concurrency".to_vec()];let mut buf = MultiBuf { chunks, pos: 0 };let blobid = client.put(&mut buf);println!("blobid = {}", blobid);
}

運(yùn)行信息如下:

cxx-demo$  cargo runCompiling cxx-demo v0.1.0Finished dev [unoptimized + debuginfo] target(s) in 0.41sRunning `target/debug/cxx-demo`blobid = 9851996977040795552

七、插曲:產(chǎn)生了什么?

對(duì)于好奇的人來(lái)說(shuō),很容易了解CXX為使這些函數(shù)調(diào)用工作所做的幕后工作。在CXX的正常使用過(guò)程中,您不需要這樣做,但就本教程而言,這可能具有教育意義。
CXX包含兩個(gè)代碼生成器:一個(gè)Rust生成器(即CXX::bridge屬性過(guò)程宏)和一個(gè)C++生成器。
Rust生成的代碼
通過(guò)cargo-expand可以最容易地查看程序宏的輸出。然后運(yùn)行cargo expand ::ffi宏展開(kāi)mod ffi模塊。

cxx-demo$  cargo install cargo-expand 
cxx-demo$  cargo expand ::ffi

您將看到一些非常令人不快的代碼,涉及#[repr(C)]、#[repr?], #[link_name] 和 #[export_name].。

八、C++生成的代碼

為了調(diào)試方便,cxx_build將所有生成的C++代碼鏈接到Cargo在target/cxxbridge/下的目標(biāo)目錄中。

cxx-demo$  exa -T target/cxxbridge/
target/cxxbridge
├── cxx-demo
│  └── src
│     ├── main.rs.cc -> ../../../debug/build/cxx-demo-11c6f678ce5c3437/out/cxxbridge/sources/cxx-demo/src/main.rs.cc
│     └── main.rs.h -> ../../../debug/build/cxx-demo-11c6f678ce5c3437/out/cxxbridge/include/cxx-demo/src/main.rs.h
└── rust└── cxx.h -> ~/.cargo/registry/src/github.com-1ecc6299db9ec823/cxx-1.0.0/include/cxx.h

在這些文件中,您將看到語(yǔ)言邊界中存在的任何CXX Rust類(lèi)型的聲明或模板(如Rust::Slicefor&[T])以及與extern函數(shù)對(duì)應(yīng)的extern“C”簽名。
如果CXX C++代碼生成器更適合您的工作流程,它也可以作為一個(gè)獨(dú)立的可執(zhí)行文件提供,將生成的代碼輸出到stdout。

cxx-demo$  cargo install cxxbridge-cmd
cxx-demo$  cxxbridge src/main.rs

九、共享數(shù)據(jù)結(jié)構(gòu)

到目前為止,上述兩個(gè)方向的調(diào)用只使用了不透明類(lèi)型,而不是共享結(jié)構(gòu)。
共享結(jié)構(gòu)是數(shù)據(jù)結(jié)構(gòu),其完整定義對(duì)兩種語(yǔ)言都是可見(jiàn)的,從而可以通過(guò)值跨語(yǔ)言傳遞它們。共享結(jié)構(gòu)轉(zhuǎn)換為C++聚合初始化兼容結(jié)構(gòu),與Rust結(jié)構(gòu)的布局完全匹配。
作為此演示的最后一步,我們將使用共享結(jié)構(gòu)體BlobMetadata在Rust應(yīng)用程序和C++blobstore客戶(hù)端之間傳遞有關(guān)blob的元數(shù)據(jù)。

// src/main.rs#[cxx::bridge]
mod ffi {struct BlobMetadata {size: usize,tags: Vec<String>,}extern "Rust" {// ...}unsafe extern "C++" {// ...fn tag(&self, blobid: u64, tag: &str);fn metadata(&self, blobid: u64) -> BlobMetadata;}
}fn main() {let client = ffi::new_blobstore_client();// Upload a blob.let chunks = vec![b"fearless".to_vec(), b"concurrency".to_vec()];let mut buf = MultiBuf { chunks, pos: 0 };let blobid = client.put(&mut buf);println!("blobid = {}", blobid);// Add a tag.client.tag(blobid, "rust");// Read back the tags.let metadata = client.metadata(blobid);println!("tags = {:?}", metadata.tags);
}
// include/blobstore.h#pragma once
#include "rust/cxx.h"struct MultiBuf;
struct BlobMetadata;class BlobstoreClient {
public:BlobstoreClient();uint64_t put(MultiBuf &buf) const;void tag(uint64_t blobid, rust::Str tag) const;BlobMetadata metadata(uint64_t blobid) const;private:class impl;std::shared_ptr<impl> impl;
};// src/blobstore.cc#include "cxx-demo/include/blobstore.h"
#include "cxx-demo/src/main.rs.h"
#include <algorithm>
#include <functional>
#include <set>
#include <string>
#include <unordered_map>// Toy implementation of an in-memory blobstore.
//
// In reality the implementation of BlobstoreClient could be a large
// complex C++ library.
class BlobstoreClient::impl {friend BlobstoreClient;using Blob = struct {std::string data;std::set<std::string> tags;};std::unordered_map<uint64_t, Blob> blobs;
};BlobstoreClient::BlobstoreClient() : impl(new class BlobstoreClient::impl) {}// Add tag to an existing blob.
void BlobstoreClient::tag(uint64_t blobid, rust::Str tag) const {impl->blobs[blobid].tags.emplace(tag);
}// Retrieve metadata about a blob.
BlobMetadata BlobstoreClient::metadata(uint64_t blobid) const {BlobMetadata metadata{};auto blob = impl->blobs.find(blobid);if (blob != impl->blobs.end()) {metadata.size = blob->second.data.size();std::for_each(blob->second.tags.cbegin(), blob->second.tags.cend(),[&](auto &t) { metadata.tags.emplace_back(t); });}return metadata;
}

運(yùn)行命令:

cxx-demo$  cargo runRunning `target/debug/cxx-demo`blobid = 9851996977040795552
tags = ["rust"]

現(xiàn)在您已經(jīng)看到了本教程中涉及的所有代碼。它可以在演示目錄中以可運(yùn)行的形式一起使用https://github.com/dtolnay/cxx.您可以直接運(yùn)行它,而無(wú)需從該目錄運(yùn)行cargo run來(lái)完成上述步驟。

十、結(jié)束語(yǔ)

CXX的主要貢獻(xiàn)是它為你提供了Rust與C++的互操作性,在這種互操作性中,你編寫(xiě)的所有Rust端代碼看起來(lái)都像是在寫(xiě)普通的Rust,而C++端看起來(lái)也像是在編寫(xiě)普通的C++。
在文中,您已經(jīng)看到,所涉及的代碼都不像C,也不像通常危險(xiǎn)的“FFI膠水”,容易發(fā)生泄漏或內(nèi)存安全缺陷。
由不透明類(lèi)型、共享類(lèi)型和關(guān)鍵標(biāo)準(zhǔn)庫(kù)類(lèi)型綁定組成的表達(dá)系統(tǒng)使API能夠在語(yǔ)言邊界上進(jìn)行設(shè)計(jì),從而獲取接口的正確所有權(quán)和借用契約。
CXX發(fā)揮了Rust類(lèi)型系統(tǒng)和C++類(lèi)型系統(tǒng)的優(yōu)勢(shì)以及程序員的直覺(jué)。一個(gè)在沒(méi)有Rust背景的C++端或沒(méi)有C++背景的Rust端工作的人,將能夠運(yùn)用他們對(duì)語(yǔ)言開(kāi)發(fā)的所有常見(jiàn)直覺(jué)和最佳實(shí)踐來(lái)維護(hù)正確的FFI。

http://www.risenshineclean.com/news/7976.html

相關(guān)文章:

  • 企業(yè)域名是什么網(wǎng)站seo關(guān)鍵詞設(shè)置
  • 網(wǎng)站設(shè)計(jì)營(yíng)銷(xiāo)網(wǎng)站出租三級(jí)域名費(fèi)用
  • 做視頻網(wǎng)站視頻的軟件企業(yè)營(yíng)銷(xiāo)培訓(xùn)課程
  • 女性時(shí)尚網(wǎng)站源碼客戶(hù)關(guān)系管理
  • 有沒(méi)有免費(fèi)的微網(wǎng)站視頻營(yíng)銷(xiāo)模式有哪些
  • 昭通網(wǎng)站建設(shè)如何提高網(wǎng)站排名的方法
  • 二手站網(wǎng)站怎做優(yōu)化課程體系
  • 招聘 負(fù)責(zé)網(wǎng)站開(kāi)發(fā)網(wǎng)絡(luò)營(yíng)銷(xiāo)有什么方式
  • 網(wǎng)站做cdn百度網(wǎng)頁(yè)版入口
  • 網(wǎng)站信息發(fā)布制度建設(shè)seo網(wǎng)站優(yōu)化排名
  • 建網(wǎng)站哪便宜百度網(wǎng)站提交入口網(wǎng)址
  • 網(wǎng)頁(yè)跟網(wǎng)站的區(qū)別百度seo2022
  • 開(kāi)發(fā)app的注意事項(xiàng)seo代理計(jì)費(fèi)系統(tǒng)
  • 兩耳清風(fēng)怎么做網(wǎng)站南京網(wǎng)絡(luò)優(yōu)化培訓(xùn)
  • 校園網(wǎng)站建設(shè)論文域名大全查詢(xún)
  • wordpress+4.9+google蘋(píng)果aso優(yōu)化
  • 做網(wǎng)站還要寫(xiě)文章嗎品牌運(yùn)營(yíng)中心
  • 做圖片網(wǎng)站用什么程序百度地圖導(dǎo)航手機(jī)版免費(fèi)下載
  • 可以先做網(wǎng)站后備案么app拉新推廣平臺(tái)有哪些
  • 2345網(wǎng)址導(dǎo)航手機(jī)上網(wǎng)導(dǎo)航下載seo網(wǎng)絡(luò)推廣教程
  • 秦皇島建設(shè)網(wǎng)站品牌宣傳方式
  • 網(wǎng)絡(luò)營(yíng)銷(xiāo)方式的使用方法搜索引擎優(yōu)化有哪些要點(diǎn)
  • 長(zhǎng)春關(guān)鍵詞推廣快速排名優(yōu)化seo
  • 網(wǎng)頁(yè)設(shè)計(jì)與實(shí)現(xiàn)論文杭州seo公司排名
  • 濟(jì)寧營(yíng)銷(xiāo)網(wǎng)站建設(shè)長(zhǎng)沙網(wǎng)站優(yōu)化排名推廣
  • 加強(qiáng)兩微一端和門(mén)戶(hù)網(wǎng)站建設(shè)云資源軟文發(fā)布平臺(tái)
  • 代購(gòu)網(wǎng)站建設(shè)網(wǎng)絡(luò)營(yíng)銷(xiāo)平臺(tái)有哪些?
  • 武漢網(wǎng)站多少百度網(wǎng)址導(dǎo)航
  • 南山做網(wǎng)站推廣樂(lè)云seo最新?tīng)I(yíng)銷(xiāo)模式
  • 網(wǎng)站給他人做付刑事責(zé)任現(xiàn)在什么app引流效果好