前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[知者行之始|行者知之成]C/C++程序在浏览器端运行DemoCode/*WebAssembly从入门到放弃*/

[知者行之始|行者知之成]C/C++程序在浏览器端运行DemoCode/*WebAssembly从入门到放弃*/

作者头像
周星星9527
发布2020-02-25 09:30:06
6680
发布2020-02-25 09:30:06
举报
文章被收录于专栏:javascript趣味编程

编译器下载和配置参考[WebAssembly从入门到放弃] Emscripten1.39.4工具链的安装与简单使用。本文介绍将C程序编译后在浏览器端运行的例子。

1. 搭建服务器

服务器使用Express框架,安装参考[物联网loT]树莓派实现局域网内LED亮灭,代码如下:

代码语言:javascript
复制
// Express
const express = require('express')
const app = express()

// public文件夹作为服务器根目录
app.use( express.static('public', {
  setHeaders: (res, path, stat) => {
    // Serve .wasm files with correct mime type
    if (path.endsWith('.wasm')) {
      res.set('Content-Type', 'application/wasm')
    }
  }
}) )

// 开启服务器
app.listen( 8888, () => console.log('Server running on port 8888!') )

2. C程序及其编译

2.1 程序demo.c

其中getPoints函数返回了100个坐标点,要给js使用。

代码语言:javascript
复制
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <emscripten.h>

// 点集数量
#define NUM_POINTS 100

// 坐标点的数据结构
struct Point {
  int x;  // x 坐标值
  int y;  // y 坐标值
};

// 坐标点存储
struct Point points[NUM_POINTS];

// 随机整数生成函数
int getRandInt(max) {
  return (rand() % max);
}

// 主函数
int main() {
  // 初始化伪随机数
  srand(time(NULL));

  // 创建点集实例
  for( int i = 0; i < NUM_POINTS; i++ ) {
     // 设置坐标值
    points[i].x = getRandInt(666);
    points[i].y = getRandInt(666);
  }

  // 调用JS函数并传递参数
  EM_ASM({ jsDemoFun($0, $1); }, NUM_POINTS*2, 2 );
}

// 返回点集数据结构给js
struct Point * getPoints( int canvasWidth, int canvasHeight ) {
   return points;
}

2.2 编译

命令行如下:

代码语言:javascript
复制
emcc demo.c -s WASM=1 -s EXPORTED_FUNCTIONS="['_main','_getPoints']" -O3 -o demo.js

EXPORTED_FUNCTIONS指定要导数的函数列表,比如getPoints函数是要导出给js调用的,需要指明;-O3表示三级优化,如不优化,编译后文件体积会很大。

3 与js交互示例

getPoints返回的是整型数组的指针,即元素首地址,也就是在内存(buffer)中的地址,使用Int32Array读取内存buffer中长度为dataLength的数据,以整型数据类型读取。

代码语言:javascript
复制
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>WebAssembly Demo</title>
  </head>
  <body>
    <script src="demo.js"></script>
    <script>
      const jsDemoFun = ( dataLength, pointStructSize ) => {
        // 调用C语言里的程序_getPoints
        let points = new Int32Array( Module.buffer, _getPoints( 666, 888), dataLength )

        // 遍历内存中的数据,逐个读取
        for( let i = 0; i < points.length; i+=pointStructSize ) {
          // 从内存中截取数据
          let point = points.slice( i, i+pointStructSize )

          console.log(point);
        }
      }
</script>
  </body>
</html>

4测试

启动服务器,打开浏览器,地址栏输入127.0.0.1:8888。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 传输过程数值模拟学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档