2016-06-27 11 views
0

Iは、以下のパラメータでasm.jsにコンパイルされたC関数を有する:asm.jsの関数との間の二重配列を渡す

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

を次に別の充填、変換を適用し、アレイ(v1)に取り出力と同じサイズ(v2)の配列。

私はそれをコンパイルし、次のJSコードを実行します。私はgetValue(v2, "double")を実行したときに

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

は、しかし、私は(間違っている)1.297703e-318を取得し、私はgetValue(v2 + 8, "double")を実行したり、getValue(v2 + 16, "double")ときには0を返します。 (これも間違っています)。

v1の内容をコンソールからログアウトするだけでCの機能を減らしました。ガベージデータも同様に出力されるので、少なくとも二重配列の読み込みに問題があります。具体的な質問は次のとおりです。

  1. ダブル配列をasm.js関数に正しく渡すにはどうすればよいですか?
  2. asm.js関数からdouble配列を正しく返すにはどうすればよいですか?
+0

["配列"、 "番号"、 "番号"、 "番号"]は[配列]、[配列]、[番号]、[番号]]ではいけませんか? – pah

+0

@threadp:私はasmで言われました。j2 IRCチャネルは、v2がJavascript配列ではないので、代わりに「番号」を使用するために「配列」を渡すべきではありません。 – Lucas

+0

@ルーカス、その場合、なぜそれが["number"、 "number"、 "number"、 "number"]ではないのですか? –

答えて

2

私はこれに少し遅れだが、それは価値がある何のため...

JSとEmscriptenの間、私は私が持っていたことがわかりました実行時の数値型を渡すと協力 Uint8Array型の型付き配列で作業し、必要に応じてビューを別の型から変更します。このようなC関数で

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

:このような何か

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

値がプリントアウトされるはずです。 JavaScriptでにアクセスしてv1が指すメモリに書き込んでみると、ccallcwrapがスタックを渡すためにスタックを使用するため、変更が無視されます。

C側の配列を変更するには、Module._mallocを使用してEmscripten実行時にいくつかのメモリを割り当てる必要があります。これは 'ポインタ'(JavaScriptによって数値として扱われ、 cwrap)を読み書きできます。ブラウザJSコンソールに倍増し、印刷されている

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の値のリストが表示されます。

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関数:あなたは、ポインタ「間接参照」にModule.getValueを使用することができます。

明らかに、同様の方法で配列をmyfuncに渡すこともできますが、_mallocデータをクリーンアップする必要があります。そのため、変更したくない値に対しては避ける傾向があります。

関連する問題