這個文章主要描述在cheerp環境下, c++和javascript代碼減少類型轉換開銷javascript
在cheerp,基本數據類型的C ++陣列如char,unsigned char,short,unsigned short,int,unsigned int,float和double由JavaScript鍵入相應類型的陣列的支持。java
Cheerp提供了一些API來將C ++數組轉換爲底層的Typed Array對象。這對於將C ++數據直接傳遞給WebGL等瀏覽器API特別有用。c++
在cheerp裏若是對js側公開必定的方法,請仔細處理轉換程序, 應爲在某個狀況下,編譯器並無人聰明。 好比說咱們都知道在c側(常常須要) 拷貝內存, 有時候clang會把咱們的代碼交叉編譯成賦值拷貝,這個就會有問題了, 若是咱們在使用智能指針的時候,傳遞了一個超大的字節數組給cheerp,賦值拷貝的性能開銷會很大。 咱們在使用的時候必定要思考咱們的最終目標是什麼。若是是小塊的內存拷貝,那麼賦值的速度要優於大塊的memcpy方法, 若是數量級比較大,好比說操做視頻文件解密, 咱們必須使用cheerp的特有轉換API來告訴編譯器,不要這樣作。數組
TypedArrayForPointerType template < typename Tstruct TypedArrayForPointerType ;瀏覽器
模板助手,爲特定的C數據類型獲取相應的Typed Array類型。所需類型可用做::type成員。例如安全
TypedArrayForPointerType < unsigned short > :: type 如下映射適用:函數
char - > Int8Array unsigned char - > Uint8Array 短 - > Int16Array unsigned short - > Uint16Array int - > Int32Array unsigned int - > Uint32Array float - > Float32Array double - > Float64Array MakeTypedArray 該函數有兩種實現方式。二者都接受兩個參數:指向任何上述數據類型的數組的指針,以及可選的大小參數。默認值爲0,表示「直到底層數組的末尾」。返回的值是指向類型化數組實例的指針。性能
注意:返回的類型化數組引用與傳遞指針相同的內存,不進行任何複製以保證此操做的效率。修改內存時請當心,由於編譯器可能會或可能不會理解類型化數組與指針的內存相同。此函數旨在以較低的開銷將C ++數據傳遞給瀏覽器API。ui
隱式打字版本指針
template < typename P,typename T = typename TypedArrayForPointerType <P> :: type> T * MakeTypedArray(const P * ptr,size_t size = 0) 此函數返回ptr指針底層內存的類型化數組。返回類型取決於模板助手ptr的映射,並遵循TypedArrayForPointerType模板助手的映射。
明確鍵入的版本 template < typename T> T * MakeTypedArray(const void * ptr,size_t size = 0) 此函數返回ptr指針底層內存的類型化數組,返回類型必須由用戶顯式提供。任何指針類型均可以做爲傳遞ptr,但若是底層內存不是基本數據類型的數組,則結果是未定義的行爲。
MakeArrayBufferView client :: ArrayBufferView * MakeArrayBufferView(const void * ptr,size_t size = 0) 返回ptr指針底層內存的無類型ArrayBufferView 。不執行數據複製,返回的對象與ptr指針的別名相同。關於有效的內存別名的安全注意事項MakeTypedArray也是有效的MakeArrayBufferView。
static ArrayBuffer* 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]; } //{age:20, c:{age:21},hellow:"cheerp"} struct Data d ; d.age = 20; d.c = {21}; memcpy(d.hellow ,"cheerp", 7); myCppSayHello(d);///js調用wasm return cheerp::MakeArrayBufferView(array);}
輸入js把Uint8Array進來之後,通過咱們的處理,若是返回的話,最好使用MakeArrayBufferView 把咱們的智能指針包裝成js的ArrayBuffer對象返回。