马兰花开 發表於 2021-5-5 17:14:00

在Javascript中调用C/C++【Emscripten】

<p>本文介绍Emscripten - 用于将C/C++的代码向Javascript转换。可用于如这样一个应用场景:有一份历史代码用C/C++实现,开发者需要用Js调用其中的代码。</p>
<p>介绍Emscripten之前,本文梳理asm.js和WebAssembly的相关知识。</p>
<p>&nbsp;</p>
<h1>一. asm.js</h1>
<p>官方网站:http://asmjs.org/spec/latest/</p>
<p>虽然名字叫“asm.js”,虽然asm.js也可以直接用javascript来编写,但是这样写出来的代码可读性非常差。</p>
<p>而且asm.js的初衷就是将C/C++程序移植到浏览器上来。</p>
<p>所以通常的做法是使用C/C++这样的静态类型和手动回收内存的语言编写程序,然后使用编译器将编写的程序编译为asm.js。</p>
<p>在Wasm出现之前,emscripten将C/C++编译成asm.js,步骤如下:</p>
<p><img src="https://img2020.cnblogs.com/blog/1507862/202105/1507862-20210505164727828-962057291.png"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h1>二. WebAssembly (WASM)</h1>
<p>官方:https://webassembly.org/</p>
<p><span>WebAssembly(缩写为</span><em>Wasm</em><span><span>)是用于基于堆栈的虚拟机的二进制指令格式。</span><span>Wasm被设计为编程语言的可移植编译目标,从而可以在Web上为客户端和服务器应用程序进行部署。</span></span></p>
<p><span>比起asm.js,将源代码编译成wasm调用时效率更高,而且对于源代码的保护更好,也是现在的emscripten默认格式。</span></p>
<p><strong>注:</strong>目前主流的浏览器均已在2018年、2019年左右支持了assembly等。而ASM.js支持所有浏览器运行,因为asm.js本质上还是js,将其他语言编译成为js,我们将这种js成为asm.js,是与ts类似的东西。而assembly是字节码,直接更加底层,已经不是js了,类似于一种flash一样的技术了,但是是浏览器内置的,必须由浏览器实现,如果浏览器不支持,就不能运行,可以预见的是,会有浏览器兼容性问题,另外,底层bug更加难以调试和发现。</p>
<p>google地图早先只能在chrome中使用的原因就是,其本身使用相当部分的native代码,所以google地图才能在web中进行渲染。后面也逐渐切换到webassembly了。</p>
<p>附:一些使用webassembly的项目https://blog.csdn.net/VhWfR2u02Q/article/details/79257270</p>
<p>&nbsp;</p>
<h1>三. Emscripten</h1>
<p>详细教程见官方网站,本文列举一些重点。</p>
<h3>3.1 下载和安装</h3>
<p>Emscripten需要Git下载并安装,依次用以下命令。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(51, 153, 102, 1)"># Get the emsdk repo</span>
git clone https://github.com/emscripten-core/emsdk.git

<span style="color: rgba(51, 153, 102, 1)"># Enter that directory</span>
cd emsdk

<span style="color: rgba(51, 153, 102, 1)"># Fetch the latest version of the emsdk (not needed the first time you clone)</span>
git pull

<span style="color: rgba(51, 153, 102, 1)"># Download and install the latest SDK tools.</span>
./emsdk install latest

<span style="color: rgba(51, 153, 102, 1)"># Make the "latest" SDK "active" for the current user. (writes .emscripten file)</span>
./emsdk activate latest

<span style="color: rgba(51, 153, 102, 1)"># Activate PATH and other environment variables in the current terminal
# Windows 下运行emsdk_env.bat</span>
source ./emsdk_env.sh</span></pre>
</div>
<h3>3.2 C语言示例</h3>
<h4>3.2.1 Hello World</h4>
<p>将一个带有main函数的C语言代码进行转化:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> #include &lt;stdio.h&gt;
<span style="color: rgba(0, 128, 128, 1)">2</span>
<span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> main(){
</span><span style="color: rgba(0, 128, 128, 1)">4</span>   printf(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">hello world\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">5</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">6</span> }</pre>
</div>
<p>通过命令</p>
<div class="cnblogs_code">
<pre>emcc .\input\hello_world.c -<span style="color: rgba(0, 0, 0, 1)">o .\output\hello_world.js



emcc .\input\hello_world.c </span>-o .\output\hello_world.html</pre>
</div>
<p>可以生成js或html文件。</p>
<p>这里html文件双击运行会失效,需要借助httpserver,可以通过python</p>
<div class="cnblogs_code">
<pre>python -m SimpleHTTPServer 8001</pre>
</div>
<p>通过http://localhost:8001/hello.html可以看到输出</p>
<p><img src="https://img2020.cnblogs.com/blog/1507862/202105/1507862-20210505170452809-873397395.png"></p>
<h4>3.2.2 函数</h4>
<p>实现一个简单的C语言代码,调用其中的函数。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> #include &lt;stdio.h&gt;
<span style="color: rgba(0, 128, 128, 1)"> 2</span> #include &lt;emscripten.h&gt;
<span style="color: rgba(0, 128, 128, 1)"> 3</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 0, 1)">EMSCRIPTEN_KEEPALIVE
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> sayHi() {
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span>   printf(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Hi!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">EMSCRIPTEN_KEEPALIVE
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> daysInWeek() {
</span><span style="color: rgba(0, 128, 128, 1)">11</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">7</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">13</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 0, 1)">EMSCRIPTEN_KEEPALIVE
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 255, 1)">int</span> multi2(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> input) {
</span><span style="color: rgba(0, 128, 128, 1)">16</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> input * <span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">17</span> }</pre>
</div>
<p>编译:</p>
<div class="cnblogs_code">
<pre>emcc <span style="color: rgba(0, 0, 255, 1)">function</span>.c -o <span style="color: rgba(0, 0, 255, 1)">function</span>.js -s MODULARIZE -s EXPORTED_RUNTIME_METHODS=[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">ccall</span><span style="color: rgba(128, 0, 0, 1)">'</span>] -s</pre>
</div>
<p>如果想用asm.js可以加入 <span style="font-family: &quot;courier new&quot;, courier">-s WASM=0</span></p>
<p>在nodejs中进行调用:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">var</span> factory = require("./function"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">2</span>
<span style="color: rgba(0, 128, 128, 1)">3</span> factory().then((instance) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">4</span>   instance._sayHi(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> direct calling works</span>
<span style="color: rgba(0, 128, 128, 1)">5</span>   instance.ccall("sayHi"); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> using ccall etc. also work</span>
<span style="color: rgba(0, 128, 128, 1)">6</span>   console.log(instance._daysInWeek()); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> values can be returned, etc.</span>
<span style="color: rgba(0, 128, 128, 1)">7</span>   console.log(instance._multi2(3<span style="color: rgba(0, 0, 0, 1)">));
</span><span style="color: rgba(0, 128, 128, 1)">8</span> });</pre>
</div>
<p>在html中使用:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 255, 1)">&lt;!</span><span style="color: rgba(255, 0, 255, 1)">doctype html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span>   <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">src</span><span style="color: rgba(0, 0, 255, 1)">="function.js"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span>   <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">    Module().then(
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">      instance </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=&gt;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">            instance._sayHi(); </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> direct calling works</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">            instance.ccall(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">sayHi</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">); </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> using ccall etc. also work</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">            console.log(instance._daysInWeek()); </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> values can be returned, etc.</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">            console.log(instance._multi2(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">3</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">));
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">    );
</span><span style="color: rgba(0, 128, 128, 1)">13</span>   <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<p>&nbsp;</p>
<h4>3.2.3 C++的函数和类</h4>
<p>C++可以通过CWrap将接口转换成C语言并实现,比较复杂。这里介绍另一种方式:embind</p>
<p><em>Embind</em><span>用于将C ++函数和类绑定到JavaScript,以便“正常” JavaScript以自然的方式使用编译后的代码。</span><em>Embind</em><span>还支持</span>从C ++调用JavaScript类<span>。</span></p>
<p><span><span>Embind支持绑定大多数C ++构造,包括C ++ 11和C ++ 14中引入的构造。</span><span>它唯一的重要限制是它当前不支持</span></span>具有复杂生命周期语义的原始指针<span>。</span></p>
<p>C++代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> #include &lt;emscripten/bind.h&gt;
<span style="color: rgba(0, 128, 128, 1)"> 2</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 255, 1)">using</span> <span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> emscripten;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MyClass {
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)">:
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>   MyClass(<span style="color: rgba(0, 0, 255, 1)">int</span> x, std::<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> y)
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">      : x(x)
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">      , y(y)
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">    {}
</span><span style="color: rgba(0, 128, 128, 1)">11</span>
<span style="color: rgba(0, 128, 128, 1)">12</span>   <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> incrementX() {
</span><span style="color: rgba(0, 128, 128, 1)">13</span>         ++<span style="color: rgba(0, 0, 0, 1)">x;
</span><span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">15</span>
<span style="color: rgba(0, 128, 128, 1)">16</span>   <span style="color: rgba(0, 0, 255, 1)">int</span> getX() <span style="color: rgba(0, 0, 255, 1)">const</span> { <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> x; }
</span><span style="color: rgba(0, 128, 128, 1)">17</span>   <span style="color: rgba(0, 0, 255, 1)">void</span> setX(<span style="color: rgba(0, 0, 255, 1)">int</span> x_) { x =<span style="color: rgba(0, 0, 0, 1)"> x_; }
</span><span style="color: rgba(0, 128, 128, 1)">18</span>
<span style="color: rgba(0, 128, 128, 1)">19</span>   <span style="color: rgba(0, 0, 255, 1)">static</span> std::<span style="color: rgba(0, 0, 255, 1)">string</span> getStringFromInstance(<span style="color: rgba(0, 0, 255, 1)">const</span> MyClass&amp;<span style="color: rgba(0, 0, 0, 1)"> instance) {
</span><span style="color: rgba(0, 128, 128, 1)">20</span>         <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> instance.y;
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">22</span>
<span style="color: rgba(0, 128, 128, 1)">23</span> <span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)">:
</span><span style="color: rgba(0, 128, 128, 1)">24</span>   <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> x;
</span><span style="color: rgba(0, 128, 128, 1)">25</span>   std::<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> y;
</span><span style="color: rgba(0, 128, 128, 1)">26</span> <span style="color: rgba(0, 0, 0, 1)">};
</span><span style="color: rgba(0, 128, 128, 1)">27</span>
<span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 0, 0, 1)">EMSCRIPTEN_BINDINGS(my_class_example) {
</span><span style="color: rgba(0, 128, 128, 1)">29</span>   class_&lt;MyClass&gt;(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MyClass</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">30</span>         .constructor&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>, std::<span style="color: rgba(0, 0, 255, 1)">string</span>&gt;<span style="color: rgba(0, 0, 0, 1)">()
</span><span style="color: rgba(0, 128, 128, 1)">31</span>         .function(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">incrementX</span><span style="color: rgba(128, 0, 0, 1)">"</span>, &amp;<span style="color: rgba(0, 0, 0, 1)">MyClass::incrementX)
</span><span style="color: rgba(0, 128, 128, 1)">32</span>         .property(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">x</span><span style="color: rgba(128, 0, 0, 1)">"</span>, &amp;MyClass::getX, &amp;<span style="color: rgba(0, 0, 0, 1)">MyClass::setX)
</span><span style="color: rgba(0, 128, 128, 1)">33</span>         .class_function(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">getStringFromInstance</span><span style="color: rgba(128, 0, 0, 1)">"</span>, &amp;<span style="color: rgba(0, 0, 0, 1)">MyClass::getStringFromInstance)
</span><span style="color: rgba(0, 128, 128, 1)">34</span> <span style="color: rgba(0, 0, 0, 1)">      ;
</span><span style="color: rgba(0, 128, 128, 1)">35</span> }</pre>
</div>
<p>编译:</p>
<div class="cnblogs_code">
<pre>emcc --bind -o class_cpp.js c<span style="color: rgba(0, 0, 0, 1)">lass.cpp </span></pre>
</div>
<p>前端Js调用,还不知道如何在nodejs后端调用:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 255, 1)">&lt;!</span><span style="color: rgba(255, 0, 255, 1)">doctype html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span>   <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span>   <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Module </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">      onRuntimeInitialized: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">() {
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span>         <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> instance </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">new</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Module.MyClass(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">10</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">, </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">hello</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">      instance.incrementX();
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">      console.log(instance.x); </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 12</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">      instance.x </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">20</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">      console.log(instance.x); </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 20</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">      console.log(Module.MyClass.getStringFromInstance(instance)); </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> "hello"</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">      instance.</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">delete</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">14</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">    };
</span><span style="color: rgba(0, 128, 128, 1)">15</span>   <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 128, 1)">16</span>   <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">src</span><span style="color: rgba(0, 0, 255, 1)">="class_cpp.js"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/Asp1rant/p/14732144.html
頁: [1]
查看完整版本: 在Javascript中调用C/C++【Emscripten】