2016-06-27 36 views
0

我有編譯成asm.js使用以下參數C函數傳遞函數之間的雙陣列:在asm.js

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

它需要在陣列中(v1),施加變換,然後填充另一與輸出相同大小的數組(v2)。

我編譯它,然後運行下面的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]); 

然而,當我運行getValue(v2, "double")我得到1.297703e-318(這是錯誤的),當我運行getValue(v2 + 8, "double")getValue(v2 + 16, "double")返回0 (這也是錯誤的)。

我已經減少了C函數,只是控制檯註銷v1的內容,並且它也打印出垃圾數據,所以至少在讀取傳入的雙數組時遇到問題。更具體的問題是:

  1. 如何正確地將雙數組傳遞給asm.js函數?
  2. 如何從asm.js函數正確地返回一個double數組?
+0

不應該[[array],「number」,「number」,「number」]是[「array」,「array」,「number」,「number」]? – pah

+0

@threadp:我被告知了asm。js IRC頻道,因爲v2不是一個Javascript數組,我不應該使用「數組」來傳遞它,而是使用「數字」。 – Lucas

+0

@盧卡斯,在這種情況下,爲什麼不是[「號碼」,「號碼」,「號碼」,「號碼」]? –

回答

2

我有點晚了這一點,但它的價值......

當傳遞運行時,我發現我不得不JS和Emscripten之間的數字類型的工作與Uint8Array類型鍵入的數組一起使用,如果需要,可以從其他類型更改視圖。是這樣的:

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); 

與這樣的C函數:

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

應該看到打印出來的值。請注意,如果您嘗試寫入v1所指向的內存(顯然會先刪除const)並在JavaScript中訪問v1,您會注意到您的更改將被忽略,因爲ccallcwrap使用堆棧來傳遞數組。

要改變C端的數組,你需要使用Module._malloc在Emscripten運行時分配一些內存,這會給你一個'指針'(通過JavaScript處理爲一個數字,並且被稱爲數字cwrap)你可以讀寫。您可以使用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')); 
} 

和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]; 
    } 
} 

應該看到V1的值的列表被一倍,打印的瀏覽器JS控制檯上。

顯然,您也可以使用類似的方法將數組傳遞到myfunc,但是您必須清理任何_malloc ed數據,所以我傾向於避免爲我不希望更改的值做這件事。

相關問題