久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

讓C代碼在瀏覽器中運行

 夢醉千秋 2018-11-28

 WebAssembly作為一種新興的Web技術(shù),,相關(guān)的資料和社區(qū)還不夠豐富,但其為web開發(fā)提供了一種嶄新的思路和工作方式,,未來是很有可能大放光彩的,。

使用WebAssembly,我們可以在瀏覽器中運行一些高性能,、低級別的編程語言,,可用它將大型的C和C++代碼庫比如游戲、物理引擎甚至是桌面應(yīng)用程序?qū)隬eb平臺,。

截至目前為止,,我們已經(jīng)可以在Chrome、Firefox中使用WebAssembly,,Edge和Safari對它的支持也基本完成,。這意味著很快,,就能在所有流行的瀏覽器中運行wasm了。

在這篇文章中,,我們將會演示如何將簡單的C代碼編譯為wasm,,并將其包含在網(wǎng)頁中。在此之前,,我們先來直觀的了解下WebAssembly是如何工作的,。

WebAssembly是如何工作的?

這里不涉及過多技術(shù)性的問題,。我們知道,,在今天的瀏覽器中,JavaScript是在虛擬機(VM)中執(zhí)行的,,該虛擬機能夠最大化地優(yōu)化代碼并壓榨每一絲的性能,,這也使得JavaScript稱為速度最快的動態(tài)語言之一。但盡管如此,,它還是無法與原生的C/C++代碼相媲美,。所以,WebAssembly就出現(xiàn)了,。

Wasm同樣在JavaScript虛擬機中運行,,但是它表現(xiàn)得更好,。兩者可以自由交互,、互不排斥,這樣你就同時擁有了兩者最大的優(yōu)勢——JavaScript巨大的生態(tài)系統(tǒng)和有好的語法,,WebAssembly接近原生的表現(xiàn)性能,。

大多數(shù)程序員會選擇使用C語言來編寫WebAssembly模塊,并將其編譯成.wasm文件,。這些.wasm文件并不能直接被瀏覽器識別,,所以它們需要一種稱為JavaScript膠接代碼(glue code,用于連接相互不兼容的軟件組件,,詳見:http://whatis./definition/glue-code)的東西來加載,。

WebAssembly工作原理

隨著未來WebAssembly框架和本地wasm模塊支持的發(fā)展,這一過程可能會有所縮短,。

開發(fā)前準備

編寫WebAssembly需要不少的工具,,但作為一個程序員,下面的工具你應(yīng)該大部分都已經(jīng)有了,。

1,、支持WebAssembly的瀏覽器,新版的Chrome或者Firefox均可(可以在此查看各個瀏覽器對某項內(nèi)容的支持情況:http:///#feat=wasm),。

2,、C到WebAssembly的編譯器,,推薦使用Emscripten(https://kripken./emscripten-site/docs/getting_started/downloads.html),安裝這個工具費時費力費空間,,但沒辦法,,這是目前為止最好的選擇,請仔細閱讀安裝說明,,需占用約1GB的硬盤空間,。

3、一個C編譯器/開發(fā)環(huán)境,,比如Linux下的GCC,,OS X下的Xcode,Windows下的Visual Studio,。

4,、一個簡單的本地web服務(wù)器,Linux/OS X下使用python -m SimpleHTTPServer 9000命令即可,,Windows下可安裝IIS服務(wù),。

一、編寫C代碼

下面我們編寫一個非常簡單的C語言例子,,它將會返回1-6的隨機數(shù),,在你所使用的工作目錄下,創(chuàng)建一個dice-roll.c文件,。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <emscripten/emscripten.h>
  5. // 一旦WASM模塊被加載,,main()中的代碼就會執(zhí)行
  6. int main(int argc, char ** argv) {
  7. printf("WebAssembly module loaded\n");
  8. }
  9. // 返回1-6之間的一隨機數(shù)
  10. int EMSCRIPTEN_KEEPALIVE roll_dice() {
  11. srand ( time(NULL) );
  12. return rand() % 6 + 1;
  13. }

當我們將其編譯為wasm并且在瀏覽器中加載時,main函數(shù)會自動執(zhí)行,,其中的printf將會被翻譯成console.log,。

我們想要roll_dice函數(shù)能夠在JavaScript中隨時調(diào)用,為此,,我們需要在函數(shù)名前添加EMSCRIPTEN_KEEPALIVE標記以告訴Emscripten我們的意圖,。

二、將C編譯為WebAssembly

現(xiàn)在我們已經(jīng)有了C代碼,,接下來需要將它編譯成wasm,,不僅如此,我們還需要生成相應(yīng)的JavaScript膠接代碼以便能夠真正運行起來,。

這里我們必須使用Emscripten編譯器,,你會發(fā)現(xiàn)有大量的命令行參數(shù)和編譯方法可選,經(jīng)過實踐,,我們找到了下面這個最友好最實用的組合:

emcc dice-roll.c -s WASM=1 -O3 -o index.js

各個參數(shù)含義如下:

  • emcc——代表Emscripten編譯器,;
  • dice-roll.c——包含C代碼的文件;
  • -s WASM=1——指定使用WebAssembly,;
  • -O3——代碼優(yōu)化級別,,3已經(jīng)是很高的級別了,;
  • -o index.js——指定生成包含wasm模塊所需的全部膠接代碼的JS文件;

需要注意的是,,盡管上面的emcc選項能夠很好地應(yīng)對我們這個例子,,但在更復雜的情況下,好需要使用不同的方法,,可查看官方文檔了解更多內(nèi)容:http://kripken./emscripten-site/docs/tools_reference/emcc.html#emccdoc,。

三、在瀏覽器中加載WebAssembly代碼

現(xiàn)在我們將回到熟悉的web開發(fā)領(lǐng)域,,在當前文件夾創(chuàng)建index.html文件,,引入相關(guān)的js文件與CSS文件。

  1. <!DOCTYPE html>
  2. <head>
  3. <meta charset="utf-8">
  4. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  5. <title>WebAssembly 示例</title>
  6. <meta name="viewport" content="width=device-width, initial-scale=1">
  7. <link rel="stylesheet" href="CSS/styles.css">
  8. <link rel="stylesheet" href="CSS/dice-1.0.min.css">
  9. </head>
  10. <body>
  11. <div class="dice dice-6"></div>
  12. <span>點擊以搖動篩子</span>
  13. <!-- 引入JavaScript膠節(jié)文件 -->
  14. <!-- 這將會加載WebAssembly模塊并運行其main函數(shù) -->
  15. <script src="index.js"></script>
  16. </body>
  17. </html>

至此,,項目結(jié)構(gòu)已經(jīng)完整,,如下:

WebAssembly項目結(jié)構(gòu)

style.css簡單設(shè)置一下頁面樣式:

  1. body {
  2. padding: 40px;
  3. font: normal 16px sans-serif;
  4. display: flex;
  5. flex-direction: column;
  6. }
  7. .dice {
  8. display: block !important;
  9. font-size: 80px;
  10. margin: 0 auto 20px;
  11. cursor: pointer;
  12. }
  13. span {
  14. display: block;
  15. margin: 0 auto;
  16. color: #333;
  17. }

dice-1.0.min.js是來自Github(https://github.com/diafygi/dice-css)的一個微型CSS骰子樣式庫,包括了1-6的SVG矢量圖,,可作為內(nèi)聯(lián)圖標使用,,用法與font-awesome和glyphicons相同。其代碼如下:

  1. /*
  2. * Dice.css v1.0
  3. * Code - MIT License - https://github.com/diafygi/dice-css
  4. * Images - Public Domain - https://openclipart.org/detail/105931/sixsided-dice-faces-lio-01
  5. */
  6. .dice{display:inline-block;min-height:1em;padding-left:1em;background-size:1em;background-repeat:no-repeat;}
  7. .dice-1{background-image: url("data:image/svg+xml,%3Csvg xmlns='http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' version='1.1' viewBox='0 0 76.5 76.5' height='21.6' width='21.6'%3E%3Cg transform='translate(113.25%2C-494.1)'%3E%3Cg transform='matrix(0.5%2C0%2C0%2C0.5%2C-406.5%2C374.7)'%3E%3Crect x='588' y='240.4' width='150' height='150' ry='50' rx='50' style='fill%3A%23fff%3Bstroke-width%3A3%3Bstroke%3A%23000'%2F%3E%3Ccircle transform='translate(337.5%2C87.5)' cx='325' cy='227.4' r='12.5' style='fill%3A%23000%3Bstroke-width%3A3%3Bstroke%3A%23000'%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E ");}
  8. .dice-2{background-image: url("data:image/svg+xml,%3Csvg xmlns='http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' version='1.1' viewBox='0 0 76.5 76.5' height='21.6' width='21.6'%3E%3Cstyle%3E.s0%7Bfill%3A%23000%3Bstroke-width%3A3%3Bstroke%3A%23000%3B%7D%3C%2Fstyle%3E%3Cg transform='translate(109.9%2C-505.1)'%3E%3Cg transform='matrix(0.5%2C0%2C0%2C0.5%2C-415.6%2C485.6)'%3E%3Crect x='613' y='40.4' width='150' height='150' ry='50' rx='50' style='fill%3A%23fff%3Bstroke-width%3A3%3Bstroke%3A%23000'%2F%3E%3Ccircle transform='translate(326.5%2C-148.5)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(398.5%2C-76.5)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E ");}
  9. .dice-3{background-image: url("data:image/svg+xml,%3Csvg xmlns='http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' version='1.1' viewBox='0 0 76.5 76.5' height='21.6' width='21.6'%3E%3Cstyle%3E.s0%7Bfill%3A%23000%3Bstroke-width%3A3%3Bstroke%3A%23000%3B%7D%3C%2Fstyle%3E%3Cg transform='translate(84.9%2C-515.5)'%3E%3Cg transform='matrix(0.5%2C0%2C0%2C0.5%2C-290.6%2C514.9)'%3E%3Crect x='413' y='2.9' width='150' height='150' ry='50' rx='50' style='fill%3A%23fff%3Bstroke-width%3A3%3Bstroke%3A%23000'%2F%3E%3Ccircle transform='translate(126.5%2C-186)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(198.5%2C-114)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(162.5%2C-150)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E ");}
  10. .dice-4{background-image: url("data:image/svg+xml,%3Csvg xmlns='http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' version='1.1' viewBox='0 0 76.5 76.5' height='21.6' width='21.6'%3E%3Cstyle%3E.s0%7Bfill%3A%23000%3Bstroke-width%3A3%3Bstroke%3A%23000%3B%7D%3C%2Fstyle%3E%3Cg transform='translate(90.7%2C-499.7)'%3E%3Cg transform='matrix(0.5%2C0%2C0%2C0.5%2C-302.7%2C367.8)'%3E%3Crect x='425.5' y='265.4' width='150' height='150' ry='50' rx='50' style='fill%3A%23fff%3Bstroke-width%3A3%3Bstroke%3A%23000'%2F%3E%3Ccircle transform='translate(139%2C76.5)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(139%2C148.5)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(211%2C76.5)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(211%2C148.5)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E ");}
  11. .dice-5{background-image: url("data:image/svg+xml,%3Csvg xmlns='http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' version='1.1' viewBox='0 0 76.5 76.5' height='21.6' width='21.6'%3E%3Cstyle%3E.s0%7Bfill%3A%23000%3Bstroke-width%3A3%3Bstroke%3A%23000%3B%7D%3C%2Fstyle%3E%3Cg transform='translate(89.2%2C-510.5)'%3E%3Cg transform='matrix(0.5%2C0%2C0%2C0.5%2C-194.9%2C372.3)'%3E%3Crect x='213' y='277.9' width='150' height='150' ry='50' rx='50' style='fill%3A%23fff%3Bstroke-width%3A3%3Bstroke%3A%23000'%2F%3E%3Ccircle transform='translate(-73.5%2C89)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(-73.5%2C161)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(-1.5%2C89)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(-1.5%2C161)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(-37.5%2C125)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E ");}
  12. .dice-6{background-image: url("data:image/svg+xml,%3Csvg xmlns='http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' version='1.1' viewBox='0 0 76.5 76.5' height='21.6' width='21.6'%3E%3Cstyle%3E.s0%7Bfill%3A%23000%3Bstroke-width%3A3%3Bstroke%3A%23000%3B%7D%3C%2Fstyle%3E%3Cg transform='translate(86.2%2C-500.6)'%3E%3Cg transform='matrix(0.5%2C0%2C0%2C0.5%2C-98.2%2C356.2)'%3E%3Crect x='25.5' y='290.4' width='150' height='150' ry='50' rx='50' style='fill%3A%23fff%3Bstroke-width%3A3%3Bstroke%3A%23000'%2F%3E%3Ccircle transform='translate(-261%2C101.5)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(-261%2C173.5)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(-261%2C137.5)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(-189%2C101.5)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(-189%2C173.5)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3Ccircle transform='translate(-189%2C137.5)' cx='325' cy='227.4' r='12.5' class='s0'%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E");}

由于跨源問題的存在,,我們需要一個本地服務(wù)器才能運行這個項目,。在Linux/OS X系統(tǒng)中,可以在項目目錄下運行如下命令:

python -m SimpleHTTPServer 9000

然后到瀏覽器中,,打開localhost:9000以查看這個小應(yīng)用,。按F12打開控制臺,即可看到我們在C代碼中使用printf輸出的問候語:

Chrome控制臺

四,、調(diào)用WebAssembly函數(shù)

最后一步是連接JavaScript與WebAssembly,,由于膠接代碼的存在(index.js),,這項任務(wù)變得非常簡單,,它已經(jīng)為我們處理好了所有的接線任務(wù)。

在瀏覽器中處理WebAssembly有一個非常強大的API可以使用,,在此我們不會進行深入探討因為這已經(jīng)超出了入門的范疇,,我們只需要Module接口及其ccall方法這部分即可。該方法允許我們通過函數(shù)名從C代碼中調(diào)用一個函數(shù),,然后就向一般的JS函數(shù)一樣使用就行了,。

  1. var result = Module.ccall(
  2. 'funcName', // 函數(shù)名
  3. 'number', // 返回類型
  4. ['number'], // 參數(shù)類型
  5. [42]); // 參數(shù)

調(diào)用此方法之后,result就將擁有對應(yīng)C函數(shù)的所有功能,,除函數(shù)名以外的所有參數(shù)都是可選的,。

我們也可以使用縮寫版:

  1. // 通過在函數(shù)名前添加下劃線來調(diào)用C函數(shù)
  2. var result = _funcName();

roll_dice函數(shù)無需任何參數(shù),在JavaScript代碼中調(diào)用十分簡單:

  1. <script>
  2. // 當HTML dice元素被點擊時,,其值將會被改變
  3. var dice = document.querySelector('.dice');
  4. dice.addEventListener('click', function(){
  5. // 調(diào)用C代碼中的roll_dice函數(shù)
  6. var result = _roll_dice();
  7. dice.className = "dice dice-" + result;
  8. });
  9. </script>

將上面這段代碼添加到index.html末尾,,即</body>之前即可,。

此時運行項目,即可看到結(jié)果:

骰子

總結(jié)

雖然現(xiàn)在WebAssembly還在發(fā)展的初期,,但從公布的新標準來看,,潛力巨大。在瀏覽器中運行低級語言的能力,,將會帶來全新的應(yīng)用程序與web體驗,,而這,是僅僅通過JavaScript無法使用的,。

誠然,,使用WebAssembly在當前階段還十分繁瑣,文檔需要分為多個部分,,相應(yīng)的工具也不容易使用,,并且還需要JavaScript膠接代碼才能使用wasm模塊。但隨著越來越多的人進入這個平臺,,所有這些問題都將會被解決,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多