cheerp資料型別包裝
這個文章主要描述在cheerp環境下, js和c++側資料型別的轉換和包裝內容。
1 基礎資料型別
首先我們知道javascript是弱型別的指令碼語言,開發者在開發的時候不必關注資料的型別和邊界,而c++是靜態程式語言, 在編譯階段就需要確定型別,在編譯器處理的時候可以獲得更好的優化。
我們都知道js所擁有的數值型別,(int,uint,float,double)預設不區分都是double型別儲存,這點和lua很相似。
在一般堆疊機下,如果使用函式呼叫會有大量的push,pop指令來獲取傳遞的引數,還要在內部進行根據型別包裝成可識別的型別。
cheerp的記憶體模型是平坦的,目標如果不是wasm的話, 是和js一致的,可以直接呼叫(翻譯成javascript,不需要push,pop這種指令)。
在cheerp環境下如果交織javascript和c++程式碼, cheerp會通過位移移除來替我們處理型別, 比如int型別,用js的Number左移兩位來標識。我們可以不關心這些基礎資料的轉換。
2複合資料型別
如果是js模式,cheerp會將js物件轉換成struct,或者是class類的對映,預設不推薦使用動態結構。 首先要在cheerp側擁有對應的結構定義,才能獲取和寫入屬性。
從js側生成庫給c++使用:
比如公開一個函式到c++
function window_base64_encode(s) {
return window.btoa(s);
}
我們在c++裡定義
String * window_base64_encode(String *);
cheerp 會自動給我們生成函式呼叫引數的原型,並切對映到js側.
如果是傳輸的物件我們可以使用Object* 來標識js側的物件。
Object * window_getData(String * );
如果是wasm模式,cheerp會嚴格遵守c++標準,對資料進行轉換。
如果要傳輸複合型別的資料,比如說物件那麼我們需要用struct對基礎資料進行包裝.而不是直接使基礎型別.
struct Sub {
int age ;
};
struct Data {
char hellow [20];
int age ;
struct Sub c;
};
等同於{age:20, c:{age:21},hellow:”cheerp”}
從c++呼叫js:
//JSExportAPI::test();
uint8 Indata[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
for(char i = 0; i < 16; i++) {
Indata[i] = i; ///用例
}
JSExportAPI::myJsSayHello(Indata); ///wasm呼叫js
for(char i = 0; i < 16; i++) {
std::cout << (*Indata+i)<< endl; //結果
}
從js呼叫c++
int myCppSayHello(Data a) {
cout << "hellow i am from cpp " <<endl;
cout <<"hellow="<< a.hellow <<endl;
cout <<"age="<< a.age <<endl;
cout <<"sub.age="<< a.c.age <<endl;
return 0;
}
class [[cheerp::genericjs]] JSExportAPI {
public:
JSExportAPI() {
}
static void myJsSayHello (uint8 * buffer) {
Uint8Array * t = (Uint8Array *)cheerp::MakeArrayBufferView(buffer);
auto array = cheerp::makeArrayRef(t);
for( int i = 0 ; i < array->get_length(); i++ ) {
array[i] = array[i] + 100 ;
*(buffer+i) = array[i];
}
struct Data d ;
d.age = 20;
d.c = {21};
memcpy(d.hellow ,"cheerp", 7);
myCppSayHello(d);///js呼叫wasm
}
};
[[cheerp::genericjs]] 欄位是生成js模式的程式碼。
無論是js到c++還是c++到js, cheerp轉換的開銷比一般的(ffi)的技術開銷要小很多。型別包裝也是他效能優化的基礎方式之一。
相關文章
- 基本資料型別及其包裝類(二)資料型別
- 基本資料型別及其包裝類(一)資料型別
- Java中基本資料型別和包裝型別有什麼區別?Java資料型別
- Java-API-基本資料型別包裝類JavaAPI資料型別
- Java 包裝類:原始資料型別與迭代器Java資料型別
- JS中資料型別、內建物件、包裝型別物件、typeof關係JS資料型別物件
- 【Java】基本資料型別包裝類面試題之一Java資料型別面試題
- Java基礎-基本型別和包裝型別Java型別
- 【Java】基本型別包裝類Java型別
- 向PostgreSQL資料庫插入Date型別資料包錯SQL資料庫型別
- Java 包裝類和基本型別Java型別
- java基本型別和包裝型別的“==”和equals()方法Java型別
- js資料型別之基本資料型別和引用資料型別JS資料型別
- java- 型別-轉換:基本型別以及包裝型別的轉換Java型別
- 資料型別: 資料型別有哪些?資料型別
- 資料型別及拆箱裝箱資料型別
- 區別值型別資料和引用型別資料型別
- 二十八、基本型別包裝類型別
- JavaScript中的包裝型別詳解JavaScript型別
- PHP 技巧 - 封裝基本的資料型別PHP封裝資料型別
- 資料型別,型別轉換資料型別
- 資料型別資料型別
- 面試官:兄弟,說說基本型別和包裝型別的區別吧面試型別
- JAVA中基本資料型別和引用資料型別Java資料型別
- 3. php資料型別、資料型別轉換PHP資料型別
- 你不知道的JavaScript--Item4 基本型別和基本包裝型別(引用型別)JavaScript型別
- 基本資料型別與字串型別資料型別字串
- MySQL基礎之----資料型別篇(常用資料型別)MySql資料型別
- Java中的基本資料型別與引用資料型別Java資料型別
- 包裝類型別,跳脫字元,BigDecimal,BigInteger,Ca型別字元Decimal
- JavaScript - 資料型別JavaScript資料型別
- Symbol資料型別Symbol資料型別
- 資料型別2資料型別
- JavaScript 資料型別JavaScript資料型別
- js資料型別JS資料型別
- TypeScript資料型別TypeScript資料型別
- Oracle 資料型別Oracle資料型別
- SQL 資料型別SQL資料型別