2017-08-17 9 views
4

バイトのベクトル(RustでVec<u8>)を生成し、ArrayまたはUint8ArrayとしてJSにアクセスして、WebSocketまたはIndexedDBに送信したいとします。RustからJavaScriptを使って配列をEmscriptenにコンパイルする

私はHow can I pass an array from JavaScript to Rust that has been compiled with Emscripten?を見つけました。これは私がやりたいと正反対ですが、非常に関係しています。それ以外はEmscriptenの配列型を知っていますが、正しく使用する方法はわかりません。

この作業をどのように行うかについては、ベクトルas_mut_ptrを返すようにして、Module.HEAPU8のポインタを使用してください。

main.rs

#[no_mangle] 
pub fn bytes() -> *mut u8 { 
    vec![1, 2, 3].as_mut_ptr() 
} 

fn main() {} 

index.htmlを

var Module = { 
    wasmBinaryFile: "site.wasm", 
    onRuntimeInitialized: main, 
}; 
function main() { 
    let ptr = Module._bytes(); 
    console.log(ptr); 
    console.log(Module.HEAPU8.slice(ptr, ptr + 10)); 
    console.log(Module.HEAPU8.subarray(ptr, ptr + 100)); 
    let arr = Module.cwrap('bytes', 'array', []); 
    console.log(arr()); 
} 

の一部のように見終わったコンソールの結果:

5260296 site:11:13 
Uint8Array [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] site:12:13 
Uint8Array [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90 more… ] site:13:13 
5260296 site:15:13 

最初問題は、値は空の配列を表し、2番目の呼び出しは同じメモリ位置を指しています。私は、ベクトルの長さとともに、ヒープ上のポイント先のデータへのアクセス方法を全く考えていません。

寿命が終わると(bytesの終わり)、RustがVec<u8>の書き込みを破棄するため、2つのポインタが同じメモリ位置を指している可能性があります。

申し訳ありませんがWasmとEmscriptenのいくつかの基本を逃した場合、私は今日初めて私のWasmの世界を構築しました。

+0

私はWasmのJavascript側に慣れていませんし、錆もそれほどありませんが、ここではあまりにも多くのエキスパートがいらっしゃいません。あなたを軌道に乗せるかもしれないいくつかのアイデアがあります:1.あなたは錆びているアレイを作成する必要がありますか? Javascript配列を(変更可能な)錆の参照として渡し、そこで変更することが可能です。 2. C/C++でこれを行う方法の詳細は、錆の中でどのように行うのかを知っているかもしれません。 – kazemakase

答えて

0

申し訳ありませんが、@sebkからのアイデアを取った後(ポインタのおかげで)。 This is what I came up with.

実際にうまくいくので、私はそれをすばやく説明します。 javacriptから配列にアクセスできるという表現が必要なので、主にポインタと配列の長さが必要です(JsVecで表されます)。wasmでは整数/浮動小数点数だけを渡すことができるので、未加工のポインタを返す必要があります。Boxinto_rawです。生ポインタをJsVecに返して情報を得ることができます。 Rustがベクトルを落とさないようにするには、mem::forgetを使ってベクトルを忘れる必要があります。

JavaScriptの世界では、ポインタとの値を使ってヒープ上のデータにアクセスするのと同じくらい簡単です。

次の問題は、ベクトルをドロップすることです。生ポインタを使用して、Boxを作成すると自動的に削除されます。私の理解では、JsVecオブジェクトがドロップされますが、vecまたはコンテンツはドロップされません。これは間違っている可能性がある主な領域なので、これはメモリリークに向かうのでしょうか?または、JsVecを十分に落としますか?

もう一度お手伝いしてくれてありがとう。

編集:

Yay!私はそれを働かせているようだ(要点は更新されている)。私はthis reddit comment's adviceをとり、JsBytes(名前が変更された)構造体からベクトルを構築し、ベクトル自体が削除されていることを確認しました!

これは機能し、要点はブラウザで動作します。

1

錆を書く場合と同じルールが適用されます。これは、関数が所有している値を返さなければならないことを意味します。現在、関数が返ったときにドロップされるデータへのポインタを返します。

一つは(PTR、長さ、容量)で構成され、これには2つの同様のソリューションがありますC.

に戻すには大きすぎるVec<u8>返します:

  1. リターンBox<Vec<u8>>と定義をそこから ポインタを抽出する別の関数です。

  2. は、私は後者hereを使用しています

C.

からアクセス可能である Vec独自に定義します。

+0

"と大きすぎてCに戻ることができない - それは本当ではなく、実際には意味をなさない。 「Cに戻る」というサイズ制限は何ですか?それはどこに文書化されていますか? – Shepmaster

+0

@Shepmaster Wasmは特定の整数データ型を返すことしかサポートしていないので、構造体のptr、length、capacityを返すことはできません。 –

+0

@sebkというレスポンスのおかげで、私はあなたの答えを以下に述べましたが、JSからアクセスすることはできますが、メモリが漏れていないことを確認する必要があります。 –

関連する問題