Angular/javascript에서 c 코드를 실행하는 방법 - WebAssembly

그런 일을 하는 것이 흥미롭고 멋집니다. 오랫동안 WebAssembly와 WebComponents에 대해 들어보셨을 것입니다. 여기에서 WebAssembly에 대해 살펴보겠습니다. 아래에서는 컴파일 C 코드를 사용하여 Angular 구성 요소에서 직접 호출하는 방법을 보여줍니다.

웹 어셈블리란?



WebAssembly는 네이티브에 가까운 성능으로 실행되고 웹에서 실행될 수 있도록 컴파일 대상이 있는 C/C++, C# 및 Rust와 같은 언어를 제공하는 컴팩트한 바이너리 형식의 저수준 어셈블리 유사 언어입니다. 또한 JavaScript와 함께 실행되도록 설계되어 둘 다 함께 작동할 수 있습니다.

처리가 실시간으로 이루어지도록 각도 응용 프로그램에서 c로 작성된 오디오 처리 기능을 실행해야 했습니다. 따라서 저는 이 WebAssembly 개념을 사용해야 했습니다.

단계


  • Angular 또는 일반 JS에서 사용하려면 처음에 emscripten's emsdk 을 설치해야 합니다. 이 SDK는 c 코드를 js로 컴파일합니다.

  • 터미널을 열고 아래 명령을 입력하여 설치하십시오. 이것은 로컬 설치입니다. 모든 것을 하나의 git repo에 보관할 수 있도록 프로젝트 루트 폴더 내에 설치하고 있습니다.

    $ git clone https://github.com/juj/emsdk.git
    $ cd emsdk
    $ ./emsdk install latest
    $ ./emsdk activate latest
    


  • tsconfig.json/app.tsconfig.json에서 모듈을 es2015에서 esnext로 변경합니다.
  • c 코드를 작성할 시간입니다. 아래는 간단한 피보나치 코드입니다. 작성하고 프로젝트 디렉토리에 fibonacci.c로 저장합니다. wasm 폴더 아래에 파일을 저장하도록 선택합니다. 이렇게하면 깨끗하고 이해하기 쉽습니다.

  • /wasm/fibonacci.c



    #include <emscripten.h>
    
    int EMSCRIPTEN_KEEPALIVE fibonacci(int n)
    {
        if (n == 0 || n == 1)
            return n;
        else
            return (fibonacci(n - 1) + fibonacci(n - 2));
    }
    


    EMSCRIPTEN_KEEPALIVE - 이것은 이 함수를 내보내기 위해 컴파일러에 언급하는 것입니다. 따라서 js에서 이 함수를 가져올 수 있습니다.
  • c 프로그램이 준비되었으며 이제 js로 변환하는 매직 명령을 실행해야 합니다. 용어로는 wasm(웹 어셈블리 모듈)이라고 합니다.

  • 터미널에서 emcc를 실행하면 "emcc 명령을 찾을 수 없습니다"라고 표시됩니다. 이를 위해서는 먼저 bash 파일을 실행하여 emcc 명령줄을 터미널로 가져와야 합니다.

    $ cd emsdk
    $ source ./emsdk_env.sh
    $ cd ..
    $ emcc \
        fibonacci.c \
        -Os \
        -o fibonacci.wasm \
        --no-entry
    


    최종 폴더 구조

    Angular에서 사용



    이것은 일이 지저분해지는 곳입니다. 인터넷에서 여러 솔루션을 시도했습니다. 특히 이https://malcoded.com/posts/web-assembly-angular/ . 그것은 매우 가능해 보였습니다. 그러나 여전히 수입과 관련된 여러 문제에 직면했고 웹팩 문제가 발생했을 때 마침내 중단되었습니다. Angular는 그것을 내부적으로 처리하고 나는 그것에 간섭하고 싶지 않습니다.

    가장 간단한 방법이 가장 좋은 방법입니다



    MDN의 공식 문서에 따라 instantiateStreaming을 사용하여 wasm 파일을 가져오고 내보낸 함수/클래스에 액세스할 수 있습니다.

    그러나 거기에는 문제가 있습니다. 가져오기 또는 http 호출을 통해서만 파일을 가져올 수 있습니다. 즉, 서버에서 파일을 제공해야 합니다. 따라서 로컬에 간단한 노드 서버를 만들고 public 폴더 아래에 wasm 파일을 추가했습니다.

    const express = require('express')
    const app = express()
    const port = 3000
    
    app.use(express.static('public'))
    app.use((req, res, next) => {
      res.set({'Access-Control-Allow-Origin':'*'});
      next();
    })
    
    app.get('/', (req, res) => {
      res.send('Hello World!');
    })
    
    app.listen(port, () => {
      console.log(`Example app listening at http://localhost:${port}`)
    })
    


    마침내 거의 끝났습니다. 이제 구성 요소에서 브라우저 내장 WebAssembly 개체를 사용하고 작업을 완료할 수 있습니다.

    app.component.ts



    import { OnInit } from '@angular/core';
    declare const WebAssembly: any;
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit, AfterViewInit {
      constructor() {}
    
      ngOnInit() {
    
        // Logs the function arguments
        const importObject = { imports: { imported_func: arg => console.log(arg) } };
    
        // Initialise the fibonacci wasm file WebAssembly.instantiateStreaming(fetch('http://localhost:3000/fibonacci.wasm'), importObject)
        .then(obj => {
    
          // Mail call of the fibonacci function
          console.log('Fibonacci of 30: ', obj.instance.exports.fibonacci(30));
    
        })
        .catch(err => console.log('fetch error: ', err));
      }
    
    }
    


    메모


  • IE에서 지원되지 않습니다. 자세한 브라우저 호환성은 here을 확인하십시오.
  • instantiateStreaming 대신 safari의 경우 인스턴스화를 사용해야 합니다. 샘플 코드here

  • 참조



  • https://github.com/boyanio/angular-wasm - 얻을 수 있는 최고의 샘플 코드입니다. 호스트이기도 합니다https://boyan.io/angular-wasm/text-to-ascii.

  • 결론



    이것은 c를 사용하는 webAssembly에 대한 나의 경험입니다. javascript/typescript가 주요 프론트엔드 언어가 되었기 때문에 이것에 대한 범위는 확실히 넓습니다. 더 많은 지원과 더 쉬운 구현 방법이 나올 수 있습니다. 따라서 지금 배우는 것은 멋진 일입니다.

    다른 방법을 알고 계시거나 제가 놓친 부분이 있다면 댓글로 알려주세요. 이 작업에 더 열심입니다.

    좋은 웹페이지 즐겨찾기