[Rust学習] WebAssemblyで複数関数登録についての問題解決の巻

2024年4月10日

Rust プログラミング 学習

t f B! P L
eyecatch 先日WebAssemblyをカンタンセットして、2つ以上の関数をセットするとエラーがでてブーブー言っていたんですが、 非常に簡単に解決することができました。 前回のブログを読んでいない人は、読んでから今回の内容を見ると、理解しやすいかと思います。 前回ブログ : [Rust学習] WebAssemblyを簡単構築

WebAssemblyで複数関数をセットする方法

WebAssemblyプロジェクトの作成

cargo new --lib multi_func

Cargo.tomlに追記

Cargo.tomlに、下記コードを追加。 [lib] crate-type = ["cdylib"]

複数関数がセットできるコード

lib.js #[no_mangle] pub fn plus(a: i32, b: i32) -> i32 { a + b } #[no_mangle] pub fn minus(a: i32, b: i32) -> i32 { a - b } #[no_mangle] pub fn multiply(a: i32, b: i32) -> i32 { a * b } #[no_mangle] pub fn devide(a: i32, b: i32) -> i32 { a / b }

コンパイル

cargo build --target=wasm32-unknown-unknown --release

index.htmlを作成

multi_func/index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Hello, WebAssembly!</title> <script> const wasm = 'target/wasm32-unknown-unknown/release/multi_func.wasm' fetch(wasm) .then(response => response.arrayBuffer()) .then(bytes => WebAssembly.instantiate(bytes, {})) .then(results => { // + const plus = results.instance.exports.plus(11, 22); console.log("Plus 11+22 : ", plus) // - const minus = results.instance.exports.minus(22, 11); console.log("Minus 22-11 : ", minus) // * const multiply = results.instance.exports.multiply(2, 3); console.log("Multiply 2*3 : ", multiply) // / const devide = results.instance.exports.devide(12, 3); console.log("Devide 12*3 : ", devide) }) </script> </head> </html>

実行

Plus 11+22 : 33 Minus 22-11 : 11 Multiply 2*3 : 6 Devide 12*3 : 4 うまくいきました。 どうやら、それぞれのfunctionに対して、"#[no_mangle]"をセットしなければいけなかったんですね。

お気づきになられただろうか・・・

勘の良いプログラマーであれば、気がついたと思いますが、 上記のプログラム、 割り算の場合、小数点が出ないというバグ付きなんですよ・・・ 試しに、以下のようにやってみると・・・ const devide = results.instance.exports.devide(12, 3); > 2 ね、2.4と返答が欲しいのに、2しか返りません。 そらそうですよね。 lib.jsの17行目の返り値指定が、i32なので、integerなんですよ。 pub fn devide(a: i32, b: i32) -> i32 {

修正対応

lib.js #[no_mangle] pub fn devide(a: i32, b: i32) -> f32 { a as f32 / b as f32 } index.html const devide = results.instance.exports.devide(12, 5); console.log("Devide 12*5 : ", devide) 実行 Devide 12*5 : 2.4000000953674316 2.4の値は取れましたが、誤差ってますね。 不必要に浮動小数点数を使うの怖い こちらのブログに書かれている通り、浮動小数点はいま現代のコンピュータ・プログラムの2進数とは相性が極めて悪いようですね。

あとがき

Javascriptにも、小数点誤差の問題はありますが、Rustのコレは、もっと頻発する感じですね。 答えが整数値になる場合は、誤差でないんですが、少数になるととたんに誤差ります。 問題が一つ解決したら、また新たな問題が勃発! まるで、マトリューシカか、だるま落としのような感じです。 まあ、それも含めてRust学習を楽しむと事にしましょう。 きっとなんかいいスニペットか、ライブラリがあるでしょう(他力本願・・・)

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ