WebAssembly는 WebBrowser상에서 수행가능한 byte code를 정의한 것으로, C나 C++로 만들어진 코드를 컴파일해서 WebAssembly (*.wasm)를 얻고, 이를 컴파일 부산물로 얻어진 Glue logic (*.js)을 이용해 WebBrowser상에서 수행시키게 된다.
이글에서는 C나 C++쪽 코드와 JavaScript 코드상에 ByteArray와 같은 대량의 data를 주고 받는 것을 설명한다.
구글링을 해보면 Heap 어쩌구 하면서 상당히 복잡한 방법이 있다.
https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97
이 글에서는 비교적 단순하게 C나 C++코드쪽 메모리 공간을 JavaScript상에서 접근하는 방법을 소개한다.
아래는 C++ 에서 Test라는 Class가 uint8_t 배열 _data 를 가지고 있고, 이것을 JavaScript 쪽 코드로 전달하는 예제 코드이다.
WebAssemly는 근본적으로 C interface이므로, C++의 경우 아래 예제처럼 s_Instances std::vector 전역 변수를 이용하여 생성되는 Class의 Instance들을 관리한다. extern "C" {} 를 통해 JavaScript로 export할 C 함수를 정의해야 한다.
아래 명령어를 이용해서 위의 test.cpp파일의 예제 코드를 emscripten toolchain을 이용해서 컴파일 한다.
참고로 사용된 emscripten toolchain 버전은 1.39.11 이다.
이제 가져다 사용하는 index.html 파일의 javascript 쪽 코드이다.
C++ 와 동일한 이름의 javascript Class를 만들고, 생성자에서 C++쪽 array의 주소를 offset으로 얻은 후,
wasmMemory.buffer에서 offset만큼, 동일한 크기로 Uint8Array를 선언해서 JavaScript쪽 byteArray 인 _data를 만들어 주면 된다.
emscripten toolchain의 버전이 올라가면서 온갖 glue logic을 가지고 있는 test.js 파일의 기능이 개선되면서
wasmMemory를 통해 간단하게 C++ 쪽 memory접근이 가능하게 된 듯 하다.
테스트는 간단하게 아래 명령어로 index.html 을 브라우징 해본다.
단순히 firefox index.html 등과 같이 하면 필요한 test.js 파일이나 test.wasm 파일을 브라우저가 가져올 수 없어서 에러가 생기므로, 아래와 같이 one shot 웹서버를 기동시켜 브라우징하는것이다.
실행하고 나면 바로 웹서버가 중지되니, 다시 테스트할려면 아래 명령어를 다시 실행해야 한다.
실행후 브라우저 Console Log를 확인해 보면 0~255 다시 255~0 까지 출력되어 있을 것이다.