- 전체
- HTML
- Web Design (웹디자인)
- XE 응용 개발
- wordpress plugin dev
- Javascript & JavaScript Application
- MEAN Stack : full stack javascript
- angular js & ionic framework
- bootstrap
- WebGL, Three.js and Babylon.js
- restful api design
- mobile web
- node.js 응용
- Cloud Service 응용
- 웹 어셈블리 개발 [WASM, WebAssembly]
- 마이크로서비스, MSA (microservice architecture)
- WebGL / WebGPU
- next.js 개발
- micro frontend (마이크로프론트앤드)
JavaScript Compiling a New C/C++ Module to WebAssembly
2018.12.01 23:00
Compiling a New C/C++ Module to WebAssembly
당신이 C/C++같은 언어로 새로운 모듈을 작성하고 있다면, 당신은 Emscripten같은 툴을 이용하여서 WebAssembly로 컴파일 할 수 있습니다. 이것이 어떻게 가능한지 봅시다!
Emscripten Environment Setup
필요한 개발 환경을 설정해 봅시다.
Prerequisites
Emscripten SDK를 설치합니다 다음의 설명서를 참고하세요. https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html
예제 컴파일 하기
환경설정을 하고난 후 Emscripten으로 어떻게 컴파일하는지 보겠습니다. Emscripten으로 컴파일 하는 방법은 여러가지가 있지만 여기서는 두가지만 다루도록 하겠습니다.
- wasm으로 컴파일 하고 코드를 실행하기 위해 HTML을 만듭니다. 그리고 wasm을 실행하기 위한 Javascript "glue"코드를 추가합니다.
- wasm으로 컴파일하고 바로 Javascript 코드를 만듭니다.
아래에서 자세히 보겠습니다.
Creating HTML and JavaScript
이것은 브라우저에서 WebAssembly 코드를 실행하는 데 필요한 모든 것을 emscripten에서 생성하도록하는 가장 간단한 방법입니다.
- 먼저 컴파일 할 예제가 필요합니다. 다음의 C 예제코드를 복사하여 hello.c 파일로 만듭니다.
#include <stdio.h> int main(int argc, char ** argv) { printf("Hello World\n"); }
- terminal을 사용하여 Emscripten 컴파일 환경에서 다음의 명령어를 실행합니다. hello.c파일과 동일한 경로에서 실행하세요
emcc hello.c -s WASM=1 -o hello.html
명령과 함께 전달 된 옵션은 다음과 같습니다.
-s WASM=1
— wasm 출력을 원한다는 것을 지정합니다. 이것을 지정하지 않으면 기본적으로 Emscripten이 asm.js를 출력합니다-o hello.html
— Emscripten이 wasm 모듈과 JavaScript "glue"코드뿐 아니라 코드를 사용하여 코드를 실행하여 HTML 페이지를 생성하여 wasm을 컴파일하고 인스턴스화하여 웹 환경에서 사용할 수 있도록 지정합니다.
이때 소스 폴더에 다음3개의 파일이 생길 것입니다.
- 바이너리 wasm 모듈 코드 (
hello.wasm
) - native c 함수와 Javascript/wasm을 번역해주는 glue코드를 포함한 자바스크립트 파일 (
hello.js
) - Wasm 코드를 로드, 컴파일 및 인스턴스화하고 브라우저에 출력을 표시하는 HTML 파일 (
hello.html
)
Running your example
이제 WebAssembly를 지원하는 브라우저에서 hello.html
을 로드해야합니다. Firefox 52+ 및 Chrome 57+, 최신 Opera에서 기본적으로 활성화됩니다 (about:config 또는 javascript.options.wasm
플래그를 활성화하여 Firefox 47+에서 wasm 코드를 실행하거나 Chrome (51+) 및 Opera (38+) chrome://flags로 이동하여 Experimental WebAssembly 플래그를 사용하도록 설정합니다.)
모든 것이 계획대로 작동했다면 Emscripten 콘솔의 "Hello world"출력이 웹 페이지와 브라우저의 JavaScript 콘솔에 나타나야합니다. 축하합니다. WebAssembly에 C를 컴파일하고 브라우저에서 실행했습니다!
Using a custom HTML template
사용자 정의 HTML 템플리트를 사용하는 방법에 대해 보도록 하겠습니다.
-
우선 다음 C코드를 새로운 폴더의 hello2.c파일로 만듭니다.
#include <stdio.h> int main(int argc, char ** argv) { printf("Hello World\n"); }
-
emsdk repo에서
shell_minimal.html
파일을 검색하십시오. 이전의 새 디렉토리에서html_template
이라는 서브 디렉토리로 복사하십시오. -
이제 Emscripten 컴파일러 환경 터미널 창에서 새 디렉토리로 이동 한 후 다음 명령을 실행합니다.
emcc -o hello2.html hello2.c -O3 -s WASM=1 --shell-file html_template/shell_minimal.html
이번 명령어의 옵션은 이전에 입력한것과 조금 다릅니다.
- 컴파일러가 여전히 JavaScript 글루 코드와
.html
을 출력한다는 것을 의미하는-o hello2.html
을 지정했습니다. - 또한
--shell-file html_template/shell_minimal.html
을 지정했습니다.이 예제는 예제를 실행할 HTML을 만드는 데 사용할 HTML 템플릿의 경로를 제공합니다.
- 컴파일러가 여전히 JavaScript 글루 코드와
-
자 이제 예제를 실행해 봅니다. 위에있는 명령어를 실행하면
hello2.html
파일을 생성해 냅니다. 생성 된 wasm을 로드하고 실행할 때 추가되는 글루 코드가있는 템플릿과 거의 동일한 내용을 갖습니다. 브라우저에서 열면 마지막 예제와 같은 결과를 볼 수 있습니다.
Calling a custom function defined in C
JavaScript에서 필요에 따라 호출 할 C 코드에 정의 된 함수가있는 경우 Emscripten ccall()
함수와 내 보낸 함수 목록에 함수를 추가하는 EMSCRIPTEN_KEEPALIVE
선언을 사용하여이 작업을 수행 할 수 있습니다 (자세한 내용은 다음 참조 : JavaScript로 컴파일 할 때 C / C ++ 소스 코드의 함수가 사라지고 처리 할 함수가없는 이유는 무엇입니까?). 이것이 어떻게 작동하는지 살펴 보겠습니다.
-
다음 코드를 새 디렉토리에
hello3.c
로 저장하십시오.#include <stdio.h> #include <emscripten/emscripten.h> int main(int argc, char ** argv) { printf("Hello World\n"); } #ifdef __cplusplus extern "C" { #endif void EMSCRIPTEN_KEEPALIVE myFunction(int argc, char ** argv) { printf("MyFunction Called\n"); } #ifdef __cplusplus } #endif
기본적으로 Emscripten이 생성 한 코드는 항상 main() 함수를 호출하고 다른 함수는 데드 코드로 제거됩니다. 함수 이름 앞에
EMSCRIPTEN_KEEPALIVE
를 쓰면 데드코드로 제거되지 않습니다.EMSCRIPTEN_KEEPALIVE
를 사용하려면emscripten.h
라이브러리를 가져와야합니다. -
이제
html_template/shell_minimal.html
을 이 새로운 디렉토리에 추가하십시오. (개발환경에 넣고 개발하는것이 편합니다). -
이제 컴파일 단계를 다시 실행 해 봅시다. 최신 디렉토리 (Emscripten 컴파일러 환경 터미널 창 내부)에서 다음 명령으로 C 코드를 컴파일하십시오. (우리가
NO_EXIT_RUNTIME
으로 컴파일 할 필요가 있다는 것을 기억하십시오.main()
이 종료 될 때 런타임이 종료 될 것입니다 - 적절한 C 에뮬레이션에 필요합니다. 예를 들어 atexits가 호출됩니다 - 컴파일 된 코드를 호출하는 것은 유효하지 않습니다 .)emcc -o hello3.html hello3.c -O3 -s WASM=1 --shell-file html_template/shell_minimal.html -s NO_EXIT_RUNTIME=1 -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall"]'
-
브라우저에 예제를 다시로드하면 이전과 같은 것을 볼 수 있습니다!
-
이제 우리는 JavaScript로부터 새로운
myFunction()
함수를 실행할 필요가 있습니다. 먼저, 첫 번째 여는<script type='text/javascript'>
태그 바로 위에<button>
을 추가해 보겠습니다.<button class="mybutton">Run myFunction</button>
-
이제 첫 번째
<script>
요소의 끝에 다음 코드를 추가합니다.document.querySelector('.mybutton').addEventListener('click', function(){ alert('check console'); var result = Module.ccall('myFunction', // name of C function null, // return type null, // argument types null); // arguments });
ccall()
을 사용하여 내 보낸 함수를 호출하는 방법을 보여줍니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.