这个文章主要描述在cheerp环境下, c++和javascript代码减小类型转换开销
在cheerp,基本数据类型的C ++阵列如char,unsigned char,short,unsigned short,int,unsigned int,float和double由JavaScript键入相应类型的阵列的支持。
Cheerp提供了一些API来将C ++数组转换为底层的Typed Array对象。这对于将C ++数据直接传递给WebGL等浏览器API特别有用。
在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。
隐式打字版本
template < typename P,typename T = typename TypedArrayForPointerType
:: 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对象返回。