zoukankan      html  css  js  c++  java
  • Webassembly 学习2 -- Js 与C 数据交互

    1、简单的C/C++ 编写

         我们可以将C 代码 编译成wasm 文件供js 调用,C 文件的写法和我们普通的C写法并没有太大区别,不需要太多的封装,连main 入口都可以丢弃。例如C实现一个简单的加法计算
    
    #include <stdio.h>
    int add(int a, int b)
    {
        int sum = a + b;
        printf("计算结果 %d
    ", sum);
        return sum;
    }
    

    编写脚本,编译C 文件成wasm 文件

    rm *.js *.wasm
    export EXPORTED_FUNCTIONS="['_add']"
    emcc add.c 
    -s EXPORTED_FUNCTIONS="${EXPORTED_FUNCTIONS}" 
    -o add.js
    

    -o 后缀名是js,指示编译器只生成wasm 以及js, 不生成默认的html 文件。

    EXPORTED_FUNCTIONS ,将函数导出

    编写html 文件调用wasm。

    <html>
      <head>
        <meta charset="utf-8">
        <title>Test</title>
      </head>
      <body>
        <script>
        Module = {};
        Module.onRuntimeInitialized = function() {
          console.log("计算结果:" + Module._add(12, 5));
        }
        </script>
        <script src="add.js"></script>
      </body>
    </html>
    

    Module是一个封装器对象,实现了C语言方法的导出,调用C 方法只需要Module._方法名即可。
    2、数据交互

      在实际的使用中,C语言经常使用malloc,free 等内存操作函数,而且一般传参都会传指针。这次在js端传入一个数组,C端完成计算并返回。
    
     修改index.html,添加以下方法
    
    function addBatch()
        {
            var num = 5;
            var inputPtr = Module._malloc(4 * 5);
            
            for(i = 0;i<num;i++)
            {
                Module.HEAP32[(inputPtr)>>2 + i] = i;
            }
     
            var sum = Module._addArry(inputPtr, num);
            console.log("数组计算结果:" + sum);
            Module._free(inputPtr);
        }
    

    JavaScript中的ArrayBuffer无法直接访问,必须通过某种类型的TypedArray方可对其进行读写,这里是将js 的数据写如一个Module.HEAP32 中,然后再传入C 中。Module._alloc /Module._free 对应于C 中的malloc/free ,需要在编译脚本中导出,不然会出现找不到

    函数的错误。

    rm *.js *.wasm
    export TOTAL_MEMORY=10485760 
    export EXPORTED_FUNCTIONS="['_add', '_addArry', '_malloc', '_free']"
    emcc add.c 
    -s EXPORTED_FUNCTIONS="${EXPORTED_FUNCTIONS}" 
    -s TOTAL_MEMORY=${TOTAL_MEMORY} 
    -o add.js
    echo "编译完成"
    

    -s TOTAL_MEMORY 这个选项要加上,不然无法分配内存,报alloc memory error 错误。

    对象 TypedArray 对应C数据类型
    Module.HEAP8 Int8Array int8
    Module.HEAP16 Int16Array int16
    Module.HEAP32 Int32Array int32
    Module.HEAPU8 Uint8Array uint8
    Module.HEAPU16 Uint16Array uint16
    Module.HEAPU32 Uint32Array uint32
    Module.HEAPF32 Float32Array float
    Module.HEAPF64 Float64Array double

    最后启动一个npm 安装http-server,启动服务器,搞定收工!

    npm install http-server -g
    http-server
    

    参考资料

    https://www.cntofu.com/book/150/zh/ch2-c-js/ch2-03-mem-model.md

  • 相关阅读:
    ssh登陆报错“WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!”的解决方法
    python错误:SyntaxError: invalid character in identifier
    Python3中出现UnicodeEncodeError: 'ascii' codec can't encode characters in ordinal not in range(128)的解决方法
    Jmeter在Mac下安装教程
    TensorFlow | win10下使用docker安装tensorflow
    Docker | 删除 image 失败的一种情况
    基础技能 | Git
    Leetcode-探索 | 两数之和
    Leetcode-探索 | 移动零
    基础复习-算法设计基础 | 复杂度计算
  • 原文地址:https://www.cnblogs.com/lidabo/p/14693498.html
Copyright © 2011-2022 走看看