简体   繁体   English

在asm.js中的函数之间传递双精度数组

[英]Passing double arrays between functions in asm.js

I have a C function compiled into asm.js with the following parameters: 我有一个使用以下参数编译为asm.js的C函数:

void myfunc(double v1[], double v2[], int v_size, double c)

It takes in an array ( v1 ), applies a transformation, then fills another array of the same size ( v2 ) with the output. 它接收一个数组( v1 ),应用转换,然后用输出填充另一个相同大小( v2 )的数组。

I compile it, and then run the following JS code: 我对其进行编译,然后运行以下JS代码:

v1 = new Array(1.0, 1.5, 2.0);
v2 = Module._malloc(8 * v1.length);

Module.ccall("myfunc", null, ["array", "number", "number", "number"], [v1, v2, v1.length, 2]);

However when I run getValue(v2, "double") I get 1.297703e-318 (which is wrong), and when I run getValue(v2 + 8, "double") or getValue(v2 + 16, "double") it returns 0 (which is also wrong). 但是,当我运行getValue(v2, "double")我得到1.297703e-318(这是错误的),而当我运行getValue(v2 + 8, "double")getValue(v2 + 16, "double")它返回0(这也是错误的)。

I've reduced the C function to just console log out the contents of v1 and it prints out garbage data as well, so at least there is an issue with reading a double array passed in. The more specific questions are: 我将C函数简化为仅控制台注销v1的内容,并且也打印出垃圾数据,因此至少在读取传入的双精度数组方面存在问题。更具体的问题是:

  1. How do I correctly pass in a double array into an asm.js function? 如何正确地将双精度数组传递给asm.js函数?
  2. How do I correctly return a double array from an asm.js function? 如何从asm.js函数正确返回双精度数组?

I'm a bit late to this, but for what it's worth... 我有点迟了,但是值得吗?

When working with passing numeric types between JS and the Emscripten run-time I've found I've had to work with Uint8Array type typed arrays, changing the view from another type if necessary. 当我在JS和Emscripten运行时之间传递数字类型时,我发现必须使用Uint8Array类型类型的数组,如有必要,可以从另一种类型更改视图。 Something like this: 像这样:

myfunc = Module.cwrap('myfunc', null, ['array']);
var v1 = new Float64Array([2.3, 4.2, 6.8, 8.9]);
var uarray = new Uint8Array(v1.buffer); // change the view to Uint8
                                        // before passing
myfunc(uarray);

with a C function like this: 具有这样的C函数:

void mfunc(const double *v1)
{
   printf("%f %f %f %f\n", v1[0], v1[1], v1[2], v1[3]);
}

should see the values printed out. 应该看到打印出来的值。 Note, if you try writing to the memory pointed to by v1 (obviously removing the const first) and accessing v1 in the JavaScript, you'll notice that your changes are ignored, as ccall and cwrap use the stack for passing the array. 请注意,如果您尝试写入v1所指向的内存(显然首先删除了const )并在JavaScript中访问v1 ,则会注意到您的更改将被忽略,因为ccallcwrap使用堆栈来传递数组。

To alter an array on the C side, you need to use Module._malloc to allocate some memory in the Emscripten run-time, this gives you a 'pointer' (treated as a number by JavaScript and referred to as a number in cwrap ) which you can read and write from. 要在C端更改数组,您需要使用Module._malloc在Emscripten运行时分配一些内存,这为您提供了一个“指针”(由JavaScript视为数字,在cwrap称为数字)您可以从中读取和写入。 You can use Module.getValue to 'dereference' the pointer: 您可以使用Module.getValue来“取消引用”指针:

myfunc = Module.cwrap('myfunc', null, ['array', 'number']);
var v1 = new Float64Array([2.3, 4.2, 6.8, 8.9]);
var uarray = new UintArray(v1.buffer);

var ptr = Module._malloc(v1.byteLength);
myfunc(uarray, ptr);

for (var i=0; i<v1.length; i++)
{
   console.log(Module.getValue(ptr+i*v1.BYTES_PER_ELEMENT, 'double'));
}

and a C function like this: 和这样的C函数:

void mfunc(const double *v1, double *v2)
{
   printf("%f %f %f %f\n", v1[0], v1[1], v1[2], v1[3]);

   int i = 0;
   for (i = 0; i < 4; i++)
   {
       v2[i] = 2 * v1[i];
   }
}

Should see a list of the values of v1 being doubled and printed on the browser JS console. 应该看到在浏览器JS控制台上将v1的值列表加倍并打印出来。

Obviously, you could also pass the array into myfunc using a similar method, but you have to clean up any _malloc ed data, so I tend to avoid doing that for values I want don't want to alter. 显然,您也可以使用类似的方法将数组传递到myfunc ,但是您必须清理所有_malloc数据,因此对于我不想更改的值,我倾向于避免这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM