zoukankan      html  css  js  c++  java
  • 用js的方式运行c程序之webassemly

    在这里就不科普webassemly的作用以及好处了,请自行百度。

    那么,怎么通过js的方式在浏览器中运行c程序呢,其中原理如下:

    可能另一张图会更详细:

    1.安装emscripten

    说明文档地址:https://emscripten.org/docs/getting_started/downloads.html

    以下步骤为macOs下命令:

    step1:克隆项目------------git clone https://github.com/emscripten-core/emsdk.git

    step2:进入项目目录--------cd emsdk

    step3:安装最新emsdk工具---./emsdk install latest

    step4:激活---------------./emsdk activate latest

    step5:执行批处理添加环境变量source ./emsdk_env.sh

    已经安装好了,看一下版本:

    2.写一个c文件(test.c)并转换.wasm

    #include <emscripten/emscripten.h>
    
    int EMSCRIPTEN_KEEPALIVE add(int a, int b) {
       return a + b;
    }
    
    int EMSCRIPTEN_KEEPALIVE fibonacci(int n) {
        if (n <= 1) {
            return n;
        } else {
            return fibonacci(n - 1) + fibonacci(n - 2);
        }
    }

    注意,红字必须,这是相比常规c文件不同的地方。

    转换命令:

    emcc test.c -Os -s WASM=1 -s SIDE_MODULE=1 -o test.wasm

    然后你就在相同目录下得到了一个test.wasm文件。

    3.通过js引入.wasm并执行其中函数

    这里我封装了一个引入.wasm文件的工具函数,代码如下:

    const importObj = {
        global: {},
        env: {
            'memory': new WebAssembly.Memory({initial: 256, maximum: 256}),
            '__memory_base': 0,
            'tableBase': 0,
            'table': new WebAssembly.Table({initial: 10, element: 'anyfunc'}),
            abort:alert
        }
    };
     
    export async function addModule(url,callback){
        fetch(url).then(response =>
            response.arrayBuffer()
        ).then(bytes => WebAssembly.instantiate(bytes,importObj)).then(results => {
            var instance = results.instance;
            var module = instance.exports;
            callback(module);
        });
    }

    index.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>WebAssemblyLearning</title>
    </head>
    <body>
        
    </body>
    
    <script type="module">
        import {addModule} from './utils/wasm.js';
        var num = 42;
        function getDuring(func,type){
            const start = Date.now();
            func(num);
            console.log(type +'执行斐波那契数列消耗时间:' +(Date.now() - start) + 'ms
    ');
        };
        addModule('./add.wasm',function(module){
            getDuring(module._fibonacci,'C程序');
        });
        function fibonacci(n) {
            if (n <= 1) {
                return n;
            } else {
                return fibonacci(n - 1) + fibonacci(n - 2);
            };
        };
        console.error('递归次数:'+ num);
        getDuring(fibonacci,'JavaScript')
    </script>
    
    </html>

    我们看到,上面通过两种不同的方式执行了一个递归次数为42的斐波那契数列求和函数,对比一下两者的性能:

    所以对于追求性能的web程序来说,webassemly将是一个很好的选择。

  • 相关阅读:
    c#,winform,progressbar+labe,联动显示进度 Virus
    答某刘
    Expert .NET 2.0 IL Assembler·一校日记 (2)
    IL 二校汇总
    历史的思考(1)
    酝酿中,写一本《你不知道的IL》
    Expert .NET 2.0 IL Assembler·一校日记
    一校 疑难汇总
    强签名
    [转] 《解剖PetShop》系列之三
  • 原文地址:https://www.cnblogs.com/eco-just/p/11689672.html
Copyright © 2011-2022 走看看