Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ko]: revise index.md webassembly/c_to_wasm #16462

Merged
merged 2 commits into from
Oct 11, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 66 additions & 58 deletions files/ko/webassembly/c_to_wasm/index.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
---
title: C/C++ 모듈을 웹어셈블리로 컴파일하기
slug: WebAssembly/C_to_Wasm
l10n:
sourceCommit: 13080fe407c8bbba19b5d6876b4706ca59c136b4
IMHOJEONG marked this conversation as resolved.
Show resolved Hide resolved
---

{{WebAssemblySidebar}}

당신이 C/C++ 같은 언어로 새로운 모듈을 작성하고 있다면, 당신은 [Emscripten](https://emscripten.org/)같은 툴을 이용해서 WebAssembly로 컴파일 할 수 있습니다. 이것이 어떻게 가능한지 봅시다.
C/C++ 같은 언어로 새로운 모듈을 작성한 경우, [Emscripten](https://emscripten.org/)같은 도구를 이용해서 WebAssembly로 컴파일 할 수 있습니다. 작동원리를 살펴보겠습니다.

## Emscripten 환경 준비하기

필요한 개발 환경을 설정해 봅시다.

### 요구 사항
### 필요한 사전 준비 사항

Emscripten SDK를 설치하기 위해, 아래 설명을 참고하세요.
<https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html>
Expand All @@ -29,123 +31,128 @@ Emscripten SDK를 설치하기 위해, 아래 설명을 참고하세요.

이 방법은 브라우저에서 WebAssembly 코드를 실행하는 데 필요한 모든 것을 emscripten에서 생성하도록 하는 가장 간단한 방법입니다.

1. 먼저 컴파일 할 예제가 필요합니다. 다음 C 예제 코드를 복사하여 hello.c 파일을 만듭니다.
1. 먼저 컴파일 할 예제가 필요합니다. 다음 C 예제 코드를 복사하여 로컬 드라이브의 새 폴더에 `hello.c` 파일을 만듭니다.

```C
```cpp
#include <stdio.h>

int main(int argc, char ** argv) {
int main() {
printf("Hello World\n");
return 0;
}
```

2. terminal을 사용하여 Emscripten 컴파일 환경에서 다음의 명령어를 실행합니다. hello.c 파일과 동일한 경로에서 실행하세요
2. Emscripten 컴파일 환경에 접속하는 데 사용한 terminal을 통ㅇ해 hello.c 파일과 동일한 폴더로 이동한 후 다음 명령을 실행하세요.

```bash
emcc hello.c -s WASM=1 -o hello.html
```
```bash
emcc hello.c -o hello.html
```

명령과 함께 전달된 옵션은 다음과 같습니다.

- `-s WASM=1` — wasm으로 결과물을 만들어 내는 옵션. 이것을 지정하지 않으면 기본적으로 Emscripten이 [asm.js](http://asmjs.org/)를 출력합니다
- `-o hello.html` — Emscripten이 코드를 실행할 HTML 페이지 (및 사용할 파일 이름)를 생성하고 wasm 모듈과 JavaScript "glue"코드를 생성하여 wasm을 컴파일하고 인스턴스화하여 웹 환경에서 사용할 수 있도록 지정합니다.
- `-o hello.html`
: Emscripten이 코드를 실행할 HTML 페이지 (및 사용할 파일 이름)를 생성하고 Wasm 모듈과 JavaScript "접착제" 코드를 생성하여 Wasm을 컴파일하고 인스턴스화하도록 지정합니다. Wasm을 사용해 웹 환경에서 사용할 수 있도록 지정합니다.

코드를 실행하면 소스 폴더에 3개의 파일이 생길 것입니다.
이 때, 소스 폴더에는 아래 파일이 있어야 합니다.

- 바이너리 wasm 모듈 코드 (`hello.wasm`)
- native c 함수와 Javascript/wasm을 번역해주는 glue코드를 포함한 자바스크립트 파일 (`hello.js`)
- 바이너리 Wasm 모듈 코드 (`hello.wasm`)
- native c 함수와 Javascript/Wasm을 번역해주는 접착제 코드를 포함한 Javascript 파일 (`hello.js`)
- Wasm 코드를 로드, 컴파일 및 인스턴스화하고 브라우저에 출력을 표시하는 HTML 파일 (`hello.html`)

### 예제 실행하기

이제 WebAssembly를 지원하는 브라우저에서 `hello.html`을 로드해야합니다. Firefox 52+ 및 Chrome 57+, 최신 Opera에서 기본적으로 활성화됩니다 (about:config 또는 `javascript.options.wasm` 플래그를 활성화하여 Firefox 47+에서 wasm 코드를 실행하거나 Chrome (51+) 및 Opera (38+) *chrome://flags*로 이동하여 Experimental WebAssembly 플래그를 사용하도록 설정합니다.)
이제 WebAssembly를 지원하는 브라우저에서 `hello.html`을 로드해야합니다. Firefox 52, Chrome 57, Edge 57, Opera 44에서 기본적으로 활성화됩니다.

> **참고:** 생성된 HTML 파일 (`hello.html`) 을 로컬 하드(예: `file://your_path/hello.html`)에서 직접 읽으려고 하면 wasm의 동기, 비동기 패치(fetch)라인에 따라 에러메시지가 표시됩니다. HTTP 서버로 HTML파일을 실행해야 합니다. [로컬 테스팅 서버를 셋업하는 방법](/ko/docs/Learn/Common_questions/set_up_a_local_testing_server)을 참고하세요.
> **참고:** 생성된 HTML 파일 (`hello.html`) 을 로컬 하드 드라이브(예: `file://your_path/hello.html`)에서 직접 열려고 하면 오류가 발생합니다(`Wasm의 동기, 비동기 가져오기가 모두 실패했습니다`라는 메시지가 표시됩니다). HTTP 서버(`http://`)로 HTML 파일을 실행해야 합니다. [로컬 테스팅 서버를 설정하는 방법](/ko/docs/Learn/Common_questions/Tools_and_setup/set_up_a_local_testing_server)을 참고하세요.

모든 것이 계획대로 작동했다면 Emscripten 콘솔의 "Hello world" 출력이 웹 페이지와 브라우저의 JavaScript 콘솔에 나타나야 합니다. 축하합니다. WebAssembly에 C를 컴파일하고 브라우저에서 실행했습니다!
모든 것이 계획대로 작동했다면, Emscripten 콘솔의 "Hello world" 출력이 웹 페이지와 브라우저의 JavaScript 콘솔에 나타나야 합니다. 축하합니다. WebAssembly로 C를 컴파일하고 브라우저에서 실행했습니다!
![image](helloworld.png)

### 사용자 정의 HTML 템플릿 사용하기

사용자 정의 HTML 템플릿을 사용하는 방법에 대해 보도록 하겠습니다.
때로는 사용자 정의 HTML 템플릿을 사용하고 싶을 수도 있습니다. 방법에 대해 알아보도록 하겠습니다.

1. 우선 다음 C 코드를 새로운 폴더의 `hello2.c`파일로 만듭니다.

```c
```cpp
#include <stdio.h>

int main(int argc, char ** argv) {
int main() {
printf("Hello World\n");
return 0;
}
```

2. emsdk 저장소에서 `shell_minimal.html` 파일을 검색하십시오. 이전의 새 디렉토리에서 `html_template`이라는 서브 디렉토리로 복사하십시오.
3. 이제 Emscripten 컴파일러 환경 터미널 창에서 새 디렉토리로 이동 한 후 다음 명령을 실행합니다.
2. emsdk 저장소에서 `shell_minimal.html` 파일을 검색하세오. 이전의 새 폴더에서 `html_template`이라는 하위 폴더로 복사하십시오.
3. Emscripten 컴파일러 환경 터미널 창에서 새 폴더로 이동 한 후 다음 명령을 실행합니다.

```bash
emcc -o hello2.html hello2.c -O3 -s WASM=1 --shell-file html_template/shell_minimal.html
emcc -o hello2.html hello2.c -O3 --shell-file html_template/shell_minimal.html
```

이번 명령어의 옵션은 이전에 입력한것과 조금 다릅니다.
이번 명령어의 옵션은 약간 다릅니다.

- 컴파일러가 여전히 JavaScript 글루 코드와 `.html`을 출력한다는 것을 의미하는 `-o hello2.html`을 지정했습니다.
- 컴파일러가 여전히 JavaScript 접착제 코드와 `.html`을 출력한다는 것을 의미하는 `-o hello2.html`을 지정했습니다.
- 코드를 최적화하는 데 사용되는 `-O3`를 지정했습니다. Emcc에는 `-O0` (최적화 없음), `-O1`, `-O2`, `-Os`, `-Oz`, `-Og` 및 `-O3`을 포함해 다른 C 컴파일러와 마찬가지로 최적화 수준이 존재합니다. `-O3`는 릴리스 빌드에 적합한 설정입니다.
- 또한 `--shell-file html_template/shell_minimal.html`을 지정했습니다.이 예제는 예제를 실행할 HTML을 만드는 데 사용할 HTML 템플릿의 경로를 제공합니다.

4. 자 이제 예제를 실행해 봅니다. 위에있는 명령어를 실행하면 `hello2.html`파일을 생성해 냅니다. 생성 된 wasm을 로드하고 실행할 때 추가되는 글루 코드가있는 템플릿과 거의 동일한 내용을 갖습니다. 브라우저에서 열면 마지막 예제와 같은 결과를 볼 수 있습니다.
4. 예제를 실행해 봅니다. 명령어를 실행하면 `hello2.html`파일을 생성합니다. 생성된 Wasm을 로드하고 실행할 때 추가되는 접착제 코드가 있는 템플릿과 거의 동일한 내용을 갖습니다. 브라우저에서 열면 마지막 예제와 같은 결과를 볼 수 있습니다.

> **참고:** **Note**: `-o` 플래그에 HTML 파일 대신 .js 파일을 지정하여 전체 HTML이 아닌 JavaScript "glue"파일\* 을 출력하도록 지정할 수 있습니다 (예 : `emcc -o hello2.js hello2.c -O3 -s WASM=1)`. 이것은 고급진 방법인데 사용자 정의 HTML을 처음부터 완전히 빌드 할 수 있습니다. 제공된 HTML 템플리트를 사용하는 것이 보통 더 쉽습니다.\* Emscripten은 메모리 할당, 메모리 누수 및 기타 여러 가지 문제를 처리하기 위해 다양한 JavaScript "접착제"코드가 필요합니다.
> **참고:** `-o` 플래그에 HTML 파일 대신 .js 파일을 지정하여 전체 HTML이 아닌 JavaScript "접착제" 파일\* 만 출력하도록 지정할 수 있습니다(예, `emcc -o hello2.js hello2.c -O3`). 이 고급 방법으로, 사용자 정의 HTML을 처음부터 완전히 빌드 할 수 있습니다. 제공된 HTML 템플릿을 사용하는 것이 보통 더 쉽습니다.
>
> Emscripten은 메모리 할당, 메모리 누수 및 기타 여러가지 문제를 처리하기 위해 다양한 JavaScript "접착제" 코드가 필요합니다.

### C 코드에서 사용자 정의된 함수 호출
### C 코드에서 사용자 정의 함수 호출

JavaScript에서 C 코드에 정의된 함수를 쓰고 싶은 경우 Emscripten `ccall()` 함수와 `EMSCRIPTEN_KEEPALIVE`(외부에서 사용가능한 함수 목록에 추가해주는 기능)을 통해 함수를 사용 할 수 있습니다 (자세한 내용은 다음 참조 : [JavaScript로 컴파일 할 때 C / C ++ 소스 코드의 함수가 사라지고 처리 할 함수가없는 이유는 무엇입니까?](https://kripken.github.io/emscripten-site/docs/getting_started/FAQ.html#why-do-functions-in-my-c-c-source-code-vanish-when-i-compile-to-javascript-and-or-i-get-no-functions-to-process)). 어떻게 작동하는지 살펴 보겠습니다.
JavaScript에서 C 코드에 정의된 함수를 쓰고 싶은 경우 Emscripten `ccall()` 함수와 `EMSCRIPTEN_KEEPALIVE`(외부에서 사용가능한 함수 목록에 추가해주는 기능)을 통해 함수를 사용 할 수 있습니다([JavaScript로 컴파일 할 때 C/C++ 소스 코드의 함수가 사라지고 처리 할 함수가없는 이유는 무엇입니까?](https://kripken.github.io/emscripten-site/docs/getting_started/FAQ.html#why-do-functions-in-my-c-c-source-code-vanish-when-i-compile-to-javascript-and-or-i-get-no-functions-to-process)를 참조하세요). 어떻게 작동하는지 살펴 보겠습니다.

1. 다음 코드를 새 디렉토리에 `hello3.c`로 저장하십시오.
1. 시작하려면, 다음 코드를 새 폴더에 `hello3.c`로 저장하세요.

```c
```cpp
#include <stdio.h>
#include <emscripten/emscripten.h>

int main(int argc, char ** argv) {
printf("Hello World\n");
int main() {
printf("Hello World\n");
return 0;
}

#ifdef __cplusplus
extern "C" {
#define EXTERN extern "C"
#else
#define EXTERN
#endif

void EMSCRIPTEN_KEEPALIVE myFunction(int argc, char ** argv) {
printf("MyFunction Called\n");
EXTERN EMSCRIPTEN_KEEPALIVE void myFunction(int argc, char ** argv) {
printf("MyFunction Called\n");
}

#ifdef __cplusplus
}
#endif
```

기본적으로 Emscripten이 생성 한 코드는 항상 `main()` 함수를 호출하고 다른 함수는 불필요한 코드로 제거됩니다. 함수 이름 앞에 `EMSCRIPTEN_KEEPALIVE`를 쓰면 데드코드로 제거되지 않습니다. `EMSCRIPTEN_KEEPALIVE`를 사용하려면 `emscripten.h` 라이브러리를 가져와야합니다.
기본적으로, Emscripten에서 생성된 코드는 항상 `main()` 함수를 호출하고 다른 함수는 불필요한 코드로 제거됩니다. 함수 이름 앞에 `EMSCRIPTEN_KEEPALIVE`를 쓰면 제거되지 않습니다. `EMSCRIPTEN_KEEPALIVE`를 사용하려면 `emscripten.h` 라이브러리를 가져와야 합니다.

> **참고:** #ifdef 블록을 포함하여 C++ 코드에 이 코드를 포함 시켜도 이 예제는 계속 작동합니다. 그냥 C코드를 넣으면 C와 C++ name mangling 규칙으로 인해 문제가 생길 수 있지만 `extern "C"`를 사용하여 이 문제를 해결하면 됩니다.
> **참고:** `#ifdef` 블록을 포함하여 C++ 코드에 이 코드를 포함 시켜도 이 예제는 계속 작동합니다. C코드를 넣으면 C와 C++ name mangling 규칙으로 인해 문제가 생길 수 있지만, C++를 사용하는 경우 외부 C 함수를 사용하여 이 문제를 해결하면 됩니다.

2. 이제 `html_template/shell_minimal.html`을 이 새로운 디렉토리에 추가하십시오. (개발환경에 넣고 개발하는것이 편합니다).
3. 이제 컴파일 단계를 다시 실행 해 봅시다. 최신 디렉토리 (Emscripten 컴파일러 환경 터미널 창 내부)에서 다음 명령으로 C 코드를 컴파일하십시오. (우리가 `NO_EXIT_RUNTIME`으로 컴파일 할 필요가 있다는 것을 기억하십시오. `main()`이 종료 될 때 런타임이 종료 될 것입니다 - 적절한 C 에뮬레이션에 필요합니다. 예를 들어 atexits가 호출됩니다 - 컴파일 된 코드를 호출하는 것은 유효하지 않습니다 .)
2. 편리성을 위해 `\{\{{ SCRIPT }}}`가 포함된 `html_template/shell_minimal.html`을 이 새로운 폴더에 콘텐츠로 추가하십시오(개발환경에 넣고 개발하는 것이 편합니다).
3. 이제 컴파일 단계를 다시 실행해 봅시다. 최신 폴더 내부(Emscripten 컴파일러 환경 터미널 창 내부)에서 다음 명령으로 C 코드를 컴파일하십시오. `NO_EXIT_RUNTIME`으로 컴파일해야 합니다. `main()`이 종료될 때 런타임이 종료 및 컴파일된 코드를 호출하는 게 유효하지 않게 됩니다. 이 방법은 적절한 C 에뮬레이션에 필요합니다. 예를 들어, [`atexit()`](https://en.cppreference.com/w/c/program/atexit) 함수가 호출되는지 확인하는 데 필요합니다.

```bash
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"]'
emcc -o hello3.html hello3.c --shell-file html_template/shell_minimal.html -s NO_EXIT_RUNTIME=1 -s "EXPORTED_RUNTIME_METHODS=['ccall']"
```

4. 브라우저에 예제를 다시로드하면 이전과 같은 것을 볼 수 있습니다!
5. 이제 JavaScript에 있는 새로운 `myFunction()` `함수를 실행`해보겠습니다. 먼저, 텍스트 에디터에서 hello.html을 열어주세요
6. `<script type='text/javascript'>` 태그 바로 위에 {{HTMLElement("button")}}을 추가해 보겠습니다.
4. 브라우저에서 예제를 다시 로드하면 이전과 동일한 내용을 볼 수 있습니다!
5. 이제 JavaScript에 있는 새로운 `myFunction()`함수를 실행해야 합니다. 먼저, 텍스트 편집기에서 hello3.html을 열어주세요.
6. 아래와 같이, `<script type='text/javascript'>` 태그 바로 위에 {{HTMLElement("button")}}을 추가합니다.

```html
<button class="mybutton">Run myFunction</button>
<button id="mybutton">Run myFunction</button>
```

7. 이제 첫 번째 {{HTMLElement("script")}} 요소의 끝에 다음 코드를 추가합니다.

```js
document.querySelector(".mybutton").addEventListener("click", function () {
document.getElementById("mybutton").addEventListener("click", () => {
alert("check console");
var result = Module.ccall(
const result = Module.ccall(
"myFunction", // name of C function
null, // return type
null, // argument types
Expand All @@ -154,12 +161,13 @@ JavaScript에서 C 코드에 정의된 함수를 쓰고 싶은 경우 Emscripten
});
```

`ccall()`을 사용하여 내보낸 함수를 호출하는 방법이었습니다.
이 방법은 `ccall()`을 사용하여 내보낸 함수를 호출하는 방법을 보여줍니다.

## 바깥 고리
## 같이 보기

- [emscripten.org](http://emscripten.org/) — learn more about Emscripten and its large variety of options.
- [Calling compiled C functions from JavaScript using ccall/cwrap](https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#calling-compiled-c-functions-from-javascript-using-ccall-cwrap)
- [Why do functions in my C/C++ source code vanish when I compile to JavaScript, and/or I get No functions to process?](https://kripken.github.io/emscripten-site/docs/getting_started/FAQ.html#why-do-functions-in-my-c-c-source-code-vanish-when-i-compile-to-javascript-and-or-i-get-no-functions-to-process)
- [WebAssembly on Mozilla Research](https://research.mozilla.org/webassembly/)
- [Compiling an Existing C Module to WebAssembly](/ko/docs/WebAssembly/existing_C_to_wasm)
- [emscripten.org](http://emscripten.org/)
: Emscripten과 다양한 옵션에 대해 자세히 알아보세요.
- [ccall/cwrap을 사용하여 JavaScript에서 컴파일된 C 함수 호출](https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#calling-compiled-c-functions-from-javascript-using-ccall-cwrap)
- [JavaScript로 컴파일할 때 C/C++ 소스 코드의 함수가 사라지거나, 처리할 함수가 없다는 메시지가 나타나는 이유는 무엇인가요?](https://kripken.github.io/emscripten-site/docs/getting_started/FAQ.html#why-do-functions-in-my-c-c-source-code-vanish-when-i-compile-to-javascript-and-or-i-get-no-functions-to-process)
- [Mozilla Research의 WebAssembly](https://research.mozilla.org/webassembly/)
- [기존 C 모듈을 WebAssembly로 컴파일](/ko/docs/WebAssembly/existing_C_to_wasm)