Hello WebAsm:第一个WebAssembly例子

Posted 车斗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hello WebAsm:第一个WebAssembly例子相关的知识,希望对你有一定的参考价值。

Hello WebAsm:第一个WebAssembly例子

概述

让浏览器能运行C语言程序,这个想法新奇而大胆。这就是 WebAssembly。它具有以下优点:

  • 高效
    WebAssembly 有一套完整的语义,实际上 wasm 是体积小且加载快的二进制格式, 其目标就是充分发挥硬件能力以达到原生执行效率。
  • 安全
    WebAssembly 运行在一个沙箱化的执行环境中,甚至可以在现有的 javascript 虚拟机中实现。在web环境中,WebAssembly将会严格遵守同源策略以及浏览器安全策略。
  • 开放
    WebAssembly 设计了一个非常规整的文本格式用来、调试、测试、实验、优化、学习、教学或者编写程序。可以以这种文本格式在web页面上查看wasm模块的源码。
  • 标准
    WebAssembly 在 web 中被设计成无版本、特性可测试、向后兼容的。WebAssembly 可以被 JavaScript 调用,进入 JavaScript 上下文,也可以像 Web API 一样调用浏览器的功能。当然,WebAssembly 不仅可以运行在浏览器上,也可以运行在非web环境下。
  • 版权保护
    这条是我加的。有些业务逻辑还是隐藏起来比较好。

环境准备

首先就是开发环境的准备工作。我是用 win10 上 virtualbox 上跑的 centos7 虚拟机。下面开始准备(用root账号)(一些 gcc, g++, cmake … 已经安装好了):

下面的过程仅仅第一次需要准备

$ yum -y install bzip2
$ yum -y install python3

查看GLIBC版本。这个要求 GLIBC_2.18 以上。

$ strings /lib64/libc.so.6 | grep ^GLIBC

如果版本低则下载 glibc-2.18.tar.gz:

$ wget https://mirrors.tuna.tsinghua.edu.cn/gnu/glibc/glibc-2.18.tar.gz

然后升级GLIBC。

glibc是gnu发布的libc库,即c运行库,glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。
很多linux的基本命令,比如cp, rm, ll, ln等,都得依赖于它,如果操作错误或者升级失败会导致系统命令不能使用,严重的造成系统退出后无法重新进入,所以操作时候需要慎重。

$ tar -zxvf  glibc-2.18.tar.gz
$ cd glibc-2.18/
$ mkdir build
$ cd build/
$ ../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
$ make -j 8
$ make install

安装 Emscripten

2012年,Mozilla 的工程师 Alon Zakai 在研究 LLVM 编译器时突发奇想:许多 3D 游戏都是用 C / C++ 语言写的,如果能将 C / C++ 语言编译成JavaScript 代码,它们不就能在浏览器里运行了吗?众所周知,JavaScript 的基本语法与 C 语言高度相似。

于是,他开始研究怎么才能实现这个目标,为此专门做了一个编译器项目 Emscripten。这个编译器可以将 C / C++ 代码编译成 JS 代码,但不是普通的 JS,而是一种叫做 asm.js 的 JavaScript 变体。

Emscripten 的底层是 LLVM 编译器,理论上任何可以生成 LLVM IR(Intermediate Representation)的语言,都可以编译生成 asm.js。 但是实际上,Emscripten 几乎只用于将 C / C++ 代码编译生成 asm.js。

C/C++ ⇒ LLVM ⇒ LLVM IR ⇒ Emscripten ⇒ asm.js

# Get the emsdk repo
$ git clone https://github.com/emscripten-core/emsdk.git

# Enter that directory
$ cd emsdk

# Fetch the latest registry of available tools.
$ ./emsdk update

# Download and install the latest SDK tools. (lastest 也可以用特定的版本代替,如1.38.45)
$ ./emsdk install latest

# Set up the compiler configuration to point to the "latest" SDK.
$ ./emsdk activate latest

# Activate PATH and other environment variables in the current terminal
$ source ./emsdk_env.sh

如果你的 emsdk 目录/path/to/emsdk/迁移到另外的位置/another-path/to/emsdk/,要重新运行:

$ cd /another-path/to/emsdk/
$ ./emsdk activate latest
$ source ./emsdk_env.sh

Hello WebAsm 第一例子

执行上面的从操作没有任何错误的话,就可以开始 WebAsm 之旅了。创建一个目录(名称随意) webasm,目录下面放入 hello.c 文件:

#include <stdio.h>

int main(int argc, char *argv[])

    printf("Hello, WebAsm!\\n");
    return 0;

在使用 emcc 命令时,要带着 -s WASM=1 参数(不然,默认将会编译成asm.js)。
如果我们想让 Emscripten 生成一个我们所写程序的html页面,并带有 wasm 和 JavaScript 文件,我们需要给输出的文件名加 .html 后缀名。
最后,当我们运行程序的时候,我们不能直接在浏览器中打开 HTML 文件,因为跨域请求是不支持 file 协议的。我们需要将我们的输出文件运行在HTTP协议上。

然后运行 emcc 编译命令(带着 -s WASM=1 参数,不然,默认将会编译成asm.js),将hello.c编译成webasm:

$ emcc hello.c -s WASM=1 -o hello.html

成功执行生成了3个文件:

hello.html
hello.js
hello.wasm

用 node 执行:

$ node hello.js

Hello, WebAsm!

然后我们可以使用 emrun 命令来创建一个 http 协议的 web server 来展示我们编译后的文件。

$ emrun --no_browser --port 8080 .

HTTP 服务开启后,您可以在浏览器中打开。如果你看到了“Hello, WebAsm!” 输出到了 Emscripten 的 控制面板,恭喜你!你的 WebAssembly 程序编译成功了!

参考链接

  • http://webassembly.org.cn/getting-started/developers-guide/
  • https://webassembly.org/
  • http://webassembly.org.cn/
  • WebAssembly 小 Demo

C/C++ 与 Javascript 互操作详见:

开始你的webasm开发之旅吧!

emscripten api

我在Win10 PC电脑上运行了VirtualBox centos7 虚拟机。当我在虚拟机里使用命令

$ emrun --no_browser --port 8080 .

就可以开启一个测试用的web服务。当服务启动之后,我就可以在我的Win10 PC笔记本上打开浏览器(firefox,chrome,edge),输入虚拟机ip地址(192.168.56.111)访问这个网址:

http://192.168.56.111:8080/hello.html

可见webasm可以工作了。

如果我想测试一下其他人的机器(如android手机)是否可以访问这个http://192.168.56.111:8080/hello.html 呢?接下来就演示这个过程。

1)Win10 PC上开启共享wifi热点,然后手机接入PC电脑。使用cmd-> ipconfig 命令查看手机进入的wifi以太网适配器, 我的是:以太网 3:

IPv4 地址 . . . . . . . . . . . . : 192.168.94.34
子网掩码  . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . : 192.168.94.1

这样在手机上的浏览器里输入 http://192.168.94.34 就可以访问Win10 PC 上的Web服务,当然前提是这个服务的确存在。我们需要安装 nginx,把服务地址 http://192.168.94.34 转发到虚拟机提供的 http://192.168.56.111:8080。即用户访问 http://192.168.94.34 的时候实际是访问 http://192.168.56.111:8080。

2)安装 nginx for windows。参考:
nginx for windows

首先下载并解压到一个目录如 C:\\DEVPACK\\nginx-1.20.1

nginx-1.20.1.zip

然后修改配置文件:C:\\DEVPACK\\nginx-1.20.1\\conf\\nginx.conf
如下(仅修改 a, b 两处,其他不变):

	http 
		# a. 增加下面的 upstream  段
	    # https://www.cnblogs.com/muhy/p/10528449.html
		upstream wasmserver 
		    server 192.168.56.111:8080;
		
	
	    server 
	        location / 
	            #root   html;
	            #index  index.html index.htm;
	            # b. 增加下面的行
				proxy_pass http://wasmserver;
	        
	

然后启动 nginx (打开 mingw64.exe 命令行窗口):

$ cd /C/DEVPACK/nginx-1.20.1/
$ ./nginx.exe

可以使用另一个 mingw64 命令行窗口查看进程:

$ tasklist -fi "imagename eq nginx.exe"

显示:

Image Name   PID Session Name       Session#    Mem Usage
===============================================================
nginx.exe         7740 Console           1      8,600 K
nginx.exe         11576 Console          1      9,052 K
3) 在接入PC共享wifi网络的手机上打开浏览器app输入地址:http://192.168.94.34/ 就可以访问虚拟机192.168.56.111上的web服务了(http://192.168.56.111:8080/)。验证 web asm 在手机上也的确可用。我测试的是华为安卓 mate10 (火狐浏览器app, BaiDuApp)。

以上是关于Hello WebAsm:第一个WebAssembly例子的主要内容,如果未能解决你的问题,请参考以下文章

Hello WebAsm:第一个WebAssembly例子

第一个python hello world

1.第一个hello word

C语言第一个程序 “Hello,world!”

Python 1-3Python的第一个程序 Hello World

django学习2-第一个Django页面:Hello World