C++ 에서 Javascript 함수를 호출하고, 반대로 Javascript에서 C++ 함수를 호출하는 예제를 포스팅 해보겠습니다. Webassembly로 컴파일 하기위해서는 C++작성된 디렉토리로 이동 후에 아래와 같이 명령어를 실행 하면 아래와 같이 wasm 파일을 생성 할 수 있습니다, (※ Webassembly 환경 세팅 및 자세한 컴파일 방법은 이전 포스팅 참고)

## WebAssembly 컴파일
emcc -lembind -o [생성 할  파일명] [변환할 파일명]

## WebAssembly 컴파일 예시
emcc -lembind -o call_analysis.js call_analysis.cpp

 


Javascript to C++ 함수 호출하기

 

C++에서 선언된 my_analysis 함수를 Javascript에서 사용 하기 위해서 

"EMSCRIPTEN_BINDINGS안에 emscripten::function("javascript에서 호출 할 함수명", C++에서 선언된 함수 반환값)"

와 같이 함수 인자를 입력하여 매핑 작업 한 후 호출하여 사용합니다.

아래 예제 소스를 기준으로 설명하면, 소스에서 emscripten::function("analysis", &my_analysis)와 같이 매핑 후에

javascript에서 analysis함수 호출시 C++의 my_analysis 함수로 반환 시켜 C++에서 선언된 함수를 호출 할 수 있습니다.

C++ 소스
#include <emscripten/bind.h>
using namespace emscripten;

float my_analysis(float a, float b, float c)
{
	return a + b * c;
}

EMSCRIPTEN_BINDINGS(my_module)
{
	emscripten::function("analysis", &my_analysis);
}
Javascript 소스
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        var Module = {
            onRuntimeInitialized: function() {
                reqForm.arg1.value = 1.5;
                reqForm.arg2.value = 3.5;
                reqForm.arg3.value = 0.5;
            }
        };

        function getResult() {
            let arg1 = parseFloat(reqForm.arg1.value);
            let arg2 = parseFloat(reqForm.arg2.value);
            let arg3 = parseFloat(reqForm.arg3.value);

            let myRet = Module.analysis(arg1, arg2, arg3);
            reqForm.result.value = myRet;
        }
    </script>
    <script src="call_analysis.js"></script>
</head>
<body>
    <form method="get" id="reqForm" onsubmit="return false;">
        <input type="text" name="arg1" value="" size="3"> +
        <input type="text" name="arg2" value="" size="3"> X
        <input type="text" name="arg3" value="" size="3"> =
        <input type="text" name="result" value="" size="3">
        <input type="button" onClick="getResult()" value="결과 얻어오기">
    </form>
</body>
</html>

C++ to Javascript 함수 호출하기

 

C++에서 Javascript 함수를 호출 하기 위해서는 EM_JS를 통하여 호출 가능합니다. 아래 예제와 같이 javascript에서 선언된 함수 jsFunction와 같이 EM_JS에서도 인자값과 인코딩 타입을 맞춰준 후에 호출하여 사용하면 됩니다.

C++ 소스
#include <iostream>
#include <string>

#include <emscripten.h>
#include <emscripten/bind.h>

EM_JS(void, call_js,(const char *subject, int len_subject, const char *msg, int len_msg), {
	jsFunction(UTF8ToString(subject, len_subject),UTF8ToString(msg, len_msg));
});

bool my_callJs()
{
	const std::string subject= "하이하이";
	const std::string msg = "나를 호출해줘~";
	
	call_js(subject.c_str(), subject.length(), msg.c_str(), msg.length());
	
	return true;
}

EMSCRIPTEN_BINDINGS(module)
{
	emscripten::function("callJs", &my_callJs);
}

 

Javascript 소스
<!DOCTYPE html>
<html lang="kr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CALL_JSFUNC</title>
    <script>
        var Module = {
            onRuntimeInitialized: () => {
                Module.callJs();
            }
        }

        const jsFunction = (subject, msg) => {
            document.querySelector('#my_div').innerText = subject;
            document.querySelector('#my_title').innerText = msg;
        }
    </script>
    <script src="call_jsfunc.js"></script>
</head>
<body>
    [ 제 목 ]
    <div id="my_div"></div>

    [ 내 용 ]
    <div id="my_title"></div>
</body>
</html> 

 

이번 포스팅은 WebAssembly에서 C++ to Javascript(Javascript to C) 함수 호출하는 방법을 정리 해봤습니다. 여기까지 지루한 글 읽어주셔서 감사합니다.

1. C언어 Source File 작성

 

Emscripten을 사용하여 WebAssembly 아래와 같이 간단한 C언어로 예제 소스를 만들어 줍니다.

Visual Studio Code, Visual Studio 2022 등 편하신 환경에서 상관 없지만, Embarcadero Dev-C++ 환경에서 구구단을 출력해주는 프로그램을 작성 하였습니다. 작성 완료 하면 다음으로 WebAssembly 컴파일을 진행 하겠습니다.

/**
File Name : multiple.c
**/
#include <stdio.h>

void multiple(int grades)
{
	for(int i = 1; i <= 9; i++)
	{
		printf("%d * %d = %d\n", grades, i, grades*i);
	}
}

int main()
{
	multiple(2);
	
	return 0;
}

 

2. Emscripten 사용하여 WebAssembly 컴파일
Emscripten 명령어

WebAssembly 컴파일(wasm 파일 생성)을 위해서는 C언어로 작성된 코드파일이 있는 디렉토리로 이동하여, 아래와 같이 명령어를 입력해 줍니다. 컴파일에 성공하면 html, js, wasm 3가지 파일이 생성됩니다.

# WebAssembly 컴파일 명령어(wasm파일 생성)
emcc [input파일명] -s WASM=1 -o [output파일명]

#실제 명령어
emcc multiple.c -s WASM=1 -o multiple.html

컴파일 성공 결과

 

다음으로 wasm 파일을 실행하기 위해서 컴파일 결과물이 있는 경로에서 python web server를 사용하여 컴파일 결과물을 실행 할 수 있습니다. 꼭 python web server가 아니더라도 apach, xampp, nginx 등 다른 서버를 사용하여 실행해도 무관합니다. 웹서버 실행에 성공하면 http://localhost:8080/multiple.html 주소로 접속하면 결과물을 확인 할 수 있습니다.

#Python 웹서버 실행
python -m http.server [포트번호]

#예시
python -m http.server 8080

파이썬 웹서버 실행 결과
wasm 파일 실행 결과

 

이번 포스팅에서는 C언어로 작성된 간단한 프로그램 소스코드를 사용해  WebAssembly 컴파일을 진행해 봤습니다. 다음 포스팅은 이어서 C언어에서 Javascript, Javascript에서 C언어로 함수를 호출하는 예제를 포스팅 해보겠습니다. 여기까지 지루한 글 읽어주셔서 감사합니다 ㅎㅎ

Webassembly 환경 구성하기

 

Webassembly 환경은 Window, Linux, MacOS 등 다양한 환경에서 구성 가능하다.

이번 포스팅에서는 Window 환경 기준으로 Webassembly 환경을 구성해볼 예정입니다.

Webassembly 환경을 구성하기 위해서는 몇 가지 프로그램을 설치 해야 합니다.

  1. 파이썬(Python) 3.x 설치 ( 다운로드 : www.python.org
  2. git 설치 ( 다운로드 : git-scm.com )
  3. Emscripten SDK(emsdk) 설치

C, C++, Rust 등에서 만들어진 코드를 Webassembly와 javascript로 컴파일 하기 위해서는 Emscripten을 설치 해야합니다.

Emscripten를 설치 하기 전에 먼저 3.x이상 버전의 파이썬과 git을 설치 해줍니다.

파이썬과 git은 공식사이트에 가면 설치 파일이 있으니 다운로드 받아 설치 해 줍니다.

Emscripten 설치하기 위해 아래와 같이 git을 통해 설치파일을 받아 설치 합니다.

 

1. Emscripten 설치하기
git clone https://github.com/emscripten-core/emsdk.git

emscripten 설치파일 받기

 

emsdk를 받았으면 다운 받은 경로로 이동해 아래와 같이 설치 합니다. 

# emsdk 설치
> emsdk.bat install [버전]

# emsdk 최신버전 설치
> emsdk.bat install latest

emsdk 설치 화면


2. Emscripten 활성화 및 환경변수 설정

 

emsdk 설치가 완료 되었으면, 아래와 같이 emsdk를 활성화하고 환경변수를 설정 하면 Webassembly 컴파일을 위한 준비가 완료 됩니다.

# emsdk 활성화
> emsdk.bat activate [버전]

# emsdk 최신버전 활성화
> emsdk.bat activate latest

# emsdk 환경변수 설정
> emsdk_env.bat

 

emsdk 활성화
emsdk 환경변수 설정


3. Emscripten 버전 정보 확인

 

emsdk가 정상 설치 되었는지 확인하기 위해 버전 확인을 해봅시다. 정상적으로 설치가 완료 되었다면 emsdk 버전 정보를 확인 할 수 있습니다.

# emsdk 버전 확인
> emcc --version
> em++ --version

 

emcc --version을 통해 버전 정보 확인
em++ --version을 통해 버전 정보를 확인

 

Windows 운영체제 환경에서 Webassembly 컴파일을 위해 환경 구성을 해봤습니다.

여기까지 지루한 포스팅 읽어주셔서 감사합니다!! ㅎㅎ

 

WeAssembly란?

 

웹어셈블리는 C, C++, C#, Rust, GO Lang, Python 등 프로그래밍 언어를 컴파일해서 어느 브라우저에서나 실행 할 수 있게 변경해주는 기술을 의미합니다.

웹브라우저에서는 원래 html, css, javascript 만 읽을 수 있습니다. 하지만 2017년부터 webassembly도 사용 가능 하게 되었고, 현재는 크롬, 사파리, 엣지, 파이어폭 다양한 브라우저에서 webassembly를 실행 시킬 수 있게 되었습니다.

그럼 WebAssembly를 언어처럼 배워야 되느냐? 아닙니다! 웹어셈블리는 개발 언어라기 보다는 브라우저에서 실행가능한 새로운 파일 형식이라고 생각 하면 될꺼 같습니다. 즉, emsdk를 사용하여 웹 브라우저에서 실행 수 있게 ".wasm" 파일로 컴파일하여 웹브라우저에서 실행 할 수 있습니다.

 

emsdk를 사용하여 wasm파일 생성

 


WebAssembly의 작

 

1.고성능

  • WebAssembly는 네이티브 코드와 비슷한 수준의 성능을 공합니다. 이는 복잡한 계산과 그래픽 처리가 필요한 작업해서

 

2. 크로스 플랫폼

  • WebAssembly는 여러 플랫폼과 브라우저에서 동일하게 작동합니다. 이를 통해 개발자는 다양한 환경에서 일관된 성능과 기능을 보장할 수 있습니다.

 

3. 언어 중립적

  • WebAssembly는 다양한 언어를 지원합니다. C, C++, C#, Rust, Golang, Python 등 다양한 언어로 작성된 코드를 WebAssembly로 컴파일하여 브라우저에서 실행 가능합니다.

 

4. 보안성

  • WebAssembly는 샌드박스 환경에서 실행되므로, 코드가 브라우저 밖으로 벗어나지 못하게하여 높은 보안성을 제공합니다. (샌드박스 환경에 대한 설명은 아래 링크 참고)

https://ko.wikipedia.org/wiki/%EC%83%8C%EB%93%9C%EB%B0%95%EC%8A%A4_(%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4_%EA%B0%9C%EB%B0%9C)

 

샌드박스 (소프트웨어 개발) - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 샌드박스(sandbox)는 보호가 필요한 어린아이들을 위해 모래통에서만 놀도록 하는데서 유래한 소프트웨어 보안 개발기법이다. 운영 환경이 저장소로부터 테스트

ko.wikipedia.org

 

 

5. 빠른 로드 타임

  • WebAssembly 모듈은 크기가 작고, 바이너리 포맷이기 때문에 빠르게 로드되고 실행될 수 있습니다. 즉, Javascript로 생성한 프로그램 보다 WebAssembly를 통해 더 같은 프로그램이라도 더 빠르게 실행 할 수 있습니다.

 

6. 기존 자바스크립트와의 호환성

  • WebAssembly는 기존 웹환경을 망가트리지 않고 동일 하게 사용 할 수 있습니다. 즉, 기존 웹 개발 환경인 HTML, CSS, Javascript와 함께 사용 될 수 있습니다.

 

WebAssembly는 이러한 잠정을 통해 복잡하고 성능이 중요한 웹 애플리케이션을 가능하게 합니다. 이미지 필터, 동영상 플레이어 등 실제로 웹으로 구현 힘들거나 구현하더라도 성능이 나오기 어려운 부분들을 다른 언어로 작성하여 웹에서 실행 함으로써 웹에서 부족한 부분을 채울 수 있습니다.

 

실제로 K사에서 웹어셈블리를 통해 이미지 필터기능의 성능 향상을 했던 사례가 있고, Auto Cad 또한 WebAssembly를 사용하여 Web에서 제품을 실행 가능하도록 했던 사례가 있습니다.

 

https://tech.kakao.com/posts/438

 

FE개발자의 성장 스토리 08 : WebAssembly 개발기 - tech.kakao.com

안녕하세요, FE플랫폼팀에서 전사 에디터 및 웹 사진 편집기를 개발하고 있는 sk...

tech.kakao.com

 

https://web.autocad.com/login

 

https://web.autocad.com/login

 

web.autocad.com

 

이번 포스팅에서는 간단히 WebAssembly에 대해서 설명 했데요. 다음 포스팅에서는 WebAssembly 컴파일 환경 구성 그리고 어떻게 컴파일 하고 실행하는지에 대해서 설명하도록 하겠습니다.

+ Recent posts