👻
React+TypeScriptでWebAssembly011。React+TypeScript。ReactTsでWasm呼び出しのまとめ
<- React+TypeScriptでWebAssembly010
React+TypeScriptでWebAssembly012 ->
Abstract
前回、WebAssemblyで、jsからC++の関数呼び出しを実装できた。
なので、今回はReact+TypeScriptからの呼び出しを実装する。
結論
今回の成果物はココ↓
前提
- WebAssemblyのビルド環境、構築済み。[環境構築]Ubuntu22.04で、WebAssemblyのOpenCV,C++,CMakeの開発環境を構築してみた。
- React+Typescriptの開発環境は構築済 [環境構築]WindowsにVSCode+React+TypeScriptの開発環境を構築してみた。
- ベースはこれ→reacttscppwasm_tmplate。
- cppmain.wasmとcppmain.jsは、前回でビルドしたのを使う。
(cppmain.wasmとcppmain.jsは下記からも取得可能)
準備
windowsだよ。
1.テンプレートのソースコード一式を取得
github取得
$ cd ~
$ git clone https://github.com/aaaa1597/reacttscppwasm_tmplate.git
$ mv reacttscppwasm_tmplate ReactTs-WebAsm011
$ cd ReactTs-WebAsm011/
2.cppmain.wasmとcppmain.jsを上書きする。
ダウンロードして上書き。
- https://github.com/aaaa1597/ReactTs-WebAsm011/blob/main/reactts/src/cppmain.js
- https://github.com/aaaa1597/ReactTs-WebAsm011/blob/main/reactts/public/wasm/cppmain.wasm
3. npm installを実行。
適当にプロジェクトフォルダを作る。
$ cd D:\Products\React.js\ReactTs-WebAsm011
$ npm install
4. VSCodeで開く。
ReactTs-WebAsm011\reacttsフォルダで右クリック。
5.cppmain.jsの修正。
見やすくするためにcppmain.jsをフォーマット。
Prettier コードフォマッターをインストールして、
↓
Shift + Ctrl + P → Format Document (Forced)を実行
↓
いい感じに整形してくれる。
6. Moduleのエクスポート化
cppmain.js(1行目)
- 1: var Module = typeof Module != 'undefined' ? Module : {};
+ 1: export var Module = typeof Module != 'undefined' ? Module : {};
7. cppmain.wasmの読込み元を修正。
cppmain.wasmをpuclic\wasmに配置するのを前提に。
cppmain.js(531行目らへん)
- 715: wasmBinaryFile = 'hello.wasm';
+ 715: wasmBinaryFile = 'wasm/cppmain.wasm';
8.CMakeLists.txtの修正
CMakeLists.txt
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s USE_ZLIB=1 -s ASSERTIONS=1 -s DISABLE_EXCEPTION_CATCHING=0 --bind -O3 -s LLD_REPORT_UNDEFINED -s DEMANGLE_SUPPORT=1")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s USE_ZLIB=1 -s ASSERTIONS=1 -s DISABLE_EXCEPTION_CATCHING=0 -lembind -O3 -s LLD_REPORT_UNDEFINED -s DEMANGLE_SUPPORT=1")
--bind を -lembind に変更。
9. App.tsx修正
App.tsx
import React, { useEffect, useRef } from 'react';
import './App.css';
class point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
toString() {
return '('+this.x+','+this.y+')';
}
}
class rect {
x: number;
y: number;
w: number;
h: number;
constructor(x: number, y: number, w: number, h: number) {
this.x=x;
this.y=y;
this.w=w;
this.h=h;
}
toString() {
return '('+this.x+','+this.y+','+this.w+','+this.h+')';
}
}
function App() {
const refWasm = useRef<any>(null)
const refTextin = useRef<HTMLTextAreaElement>(null!)
const refTextout = useRef<HTMLTextAreaElement>(null!)
/* wasm読込み */
const h = require('./cppmain.js');
h.Module.onRuntimeInitialized = () => {
console.log("Wasm loaded.");
refWasm.current = h.Module
}
useEffect(() => {
refTextin.current.rows = 5
refTextout.current.rows = 5
});
const bclick = () => {
const textout = refTextout.current;
const wasm = refWasm.current;
if(!textout && !wasm) return;
textout.value ="f1(1,2)=" + wasm.f1(1,2) + "\n";
textout.value+="f2(2.5,3.5)=" + wasm.f2(2.5, 3.5) + "\n";
textout.value+="f3('aaa', 'bbbb')=" + wasm.f3('aaa', 'bbbb') + "\n";
const arg41=[1,2,3,4], arg42=[5,6,7,8];
textout.value+="f4([1,2,3,4], [5,6,7,8])=" + wasm.f4(arg41, arg42) + "\n";
const arg51=new Uint8Array([1,2,3,4]), arg52=new Uint8Array([5,6,7,8]);
textout.value+="f5(new Uint8Array([1,2,3,4]), new Uint8Array([5,6,7,8]))=" + wasm.f5(arg51, arg52) + "\n";
const arg61=['aa','bb','cc','dd'], arg62=['ee','ff','gg','hh'];
textout.value+="f6(['aa','bb','cc','dd'], ['ee','ff','gg','hh'])=" + wasm.f6(arg61, arg62) + "\n";
const arg71=new point(1,2), arg72=new point(3,4);
↓①この行の使い方が分からん
// textout.value+="f7(new point(1,2), new point(3,4))=" + wasm.f7(arg71, arg72) + "\n";
textout.value+="f8({x2:1, y2:2},{w2:3, h2:4})=" + JSON.stringify(wasm.f8({x2:1, y2:2},{w2:3, h2:4}));
}
return (
<div className="App">
hello world!!
<button onClick={bclick}>Click</button>
<textarea id="textin" ref={refTextin}></textarea>
<textarea id="textout" ref={refTextout}></textarea>
</div>
);
}
export default App;
①の行の使い方が分からんかったけど、後はうまくいった。
10.サーバ起動
サーバ起動
$ cd D:\Products\React.js\ReactTs-WebAsm011\reactts
$ npm start
11.サーバにアクセス。
ブラウザから http://localhost:8080/ にアクセスする。
出来た!!
func7()のJSオブジェクト, JSオブジェクト, JSオブジェクトの関数呼び出しがうまくできんかったけど、今のところ使う予定ないし、宿題ってことで。
<- React+TypeScriptでWebAssembly010
React+TypeScriptでWebAssembly012 ->
Discussion