cheerp 交叉調用轉化最小開銷方式

這個文章主要描述在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來告訴編譯器,不要這樣作。數組

轉換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對象返回。

相關文章
相關標籤/搜索