日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

dotnet 将C#编译为wasm让前端html使用

發(fā)布時(shí)間:2023/12/4 C# 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 dotnet 将C#编译为wasm让前端html使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

其實(shí) dotnet 是全棧的首選,原因是因?yàn)榭梢蚤_發(fā)的方向太多,比如大本營PC端,以及后臺(tái)。還有移動(dòng)端,包括 IOS 和安卓端。現(xiàn)在還能用來寫前端,本文就來告訴大家如何在前端使用現(xiàn)有的C#代碼,通過 WebAssembly 使用 C# 的代碼支持完全靜態(tài)的網(wǎng)頁,也就是不需要任何后臺(tái)的存在。同時(shí)使用 C# 編寫的 WebAssembly 可以省去 js 編譯時(shí)間,同時(shí)使用二進(jìn)制的本地指令,運(yùn)行效率也有極大的提升。兼顧了開發(fā)的友好以及更高的性能

這需要搜 WebAssembly 就可以找到超級(jí)多的贊揚(yáng)的文章,我這里也就不需要多說了。接下來告訴大家使用一個(gè)超級(jí)簡(jiǎn)單的代碼入門

使用 WebAssmebly 的方式不會(huì)影響原有的任何業(yè)務(wù),也就是我在已經(jīng)寫了幾年的頁面里面,可以直接加入 WebAssmembly 的特性,就像多添加一個(gè) js 引用一樣。不需要對(duì)現(xiàn)有的頁面做任何的改動(dòng)

此時(shí)在 C# 里面用的代碼都是虛的,不再本文關(guān)注的范圍內(nèi),所以通過?dotnet new console -o YadernawcoLofeleabe創(chuàng)建一個(gè)控制臺(tái)項(xiàng)目

在控制臺(tái)項(xiàng)目添加一個(gè)類,這個(gè)類添加靜態(tài)方法,這個(gè)靜態(tài)方法就是讓前端調(diào)用的入口方法,給這個(gè)字符串添加字符串參數(shù),方便傳入

using System;namespace YadernawcoLofeleabe {class Program{static void Main(string[] args){Console.WriteLine("Hello World!");}}public class Example{public static string Hello(string yourName){return $"Hello {yourName}";}} }

這里的代碼不是重點(diǎn),大概就是從 Hello 拿到輸入,然后修改輸入然后輸出

接下來就是重點(diǎn)了,如何將 C# 代碼編譯為 WebAssmebly 了

這里的 C# 需要通過 mono 的輔助用于將 IL 轉(zhuǎn)換為 WebAssembly 的代碼,所以需要在Mono官網(wǎng)下載最新的 Mono 的 SDK 安裝

點(diǎn)擊下載

默認(rèn)的 Mono 將會(huì)安裝到?c:\Program Files\Mono\bin\?文件夾,如果是下載 x86 的就會(huì)安裝到?c:\Program Files(x86)\Mono\bin\?文件夾

然后下載 mono 在 wasm 的運(yùn)行時(shí),請(qǐng)?點(diǎn)擊下載?將下載的 zip 文件夾解壓縮到本地的文件夾,同時(shí)記住這個(gè)文件夾,如我將 zip 文件夾解壓縮到?f:/lindexi/mono?文件夾

此時(shí)準(zhǔn)備環(huán)境工作就完成了,下一步就是命令行編譯了。當(dāng)然這些步驟都是最基礎(chǔ)的步驟,也有封裝好的命令,也就是dotnet wasm xx.csproj?完成編譯,不過這一步需要先安裝工具(注意這個(gè)工具還沒正式發(fā)布)

通過 csc 命令將 C# 代碼編譯為 IL 文件。打開 VisualStudio 開發(fā)者命令行工具,進(jìn)入到剛才創(chuàng)建的 Program.cs 所在文件夾

csc /target:library -out:Example.dll /noconfig /nostdlib /r:f:/lindexi/mono/wasm-bcl/wasm/mscorlib.dll /r:f:/lindexi/mono/wasm-bcl/wasm/System.dll /r:f:/lindexi/mono/wasm-bcl/wasm/System.Core.dll /r:f:/lindexi/mono/wasm-bcl/wasm/Facades/netstandard.dll /r:f:/lindexi/mono/wasm-bcl/wasm/System.Net.Http.dll /r:f:/lindexi/mono/framework/WebAssembly.Bindings.dll /r:f:/lindexi/mono/framework/WebAssembly.Net.Http.dll Program.cs

注意將?f:/lindexi/mono?文件夾替換為你剛才解壓縮的 mono 運(yùn)行時(shí)所在的文件夾

上面的代碼通過引用 mono 運(yùn)行時(shí)的庫,將 Program.cs 文件編譯為 Example.dll 文件

當(dāng)然這里的 Example.dll 文件現(xiàn)在還是 IL 文件,還需要通過 mono 再次編譯為 wasm 文件。注意這里說的編譯為 wasm 并不是真的將 IL 編譯 wasm 文件,而是編譯為運(yùn)行在 wasm 的 .NET 運(yùn)行時(shí)可解析的文件。上面這句話已經(jīng)過時(shí),只是我逗比看文檔理解不對(duì),其實(shí)上面這一步編譯的 IL 文件已經(jīng)可以在 wasm 執(zhí)行了。原因是在 wasm 會(huì)先運(yùn)行一個(gè) .NET 的運(yùn)行時(shí),由 .NET 運(yùn)行時(shí)執(zhí)行這個(gè) IL 文件

單獨(dú)一個(gè) Example.dll 文件是不能直接運(yùn)行的,如上面所說,需要添加一個(gè).NET運(yùn)行時(shí)。但是一個(gè) .NET 運(yùn)行時(shí)是超級(jí)大的,難道要用戶每次打開網(wǎng)頁都下載一個(gè)這么大的運(yùn)行時(shí)?此時(shí)就需要用到?packager.exe?工具,通過這個(gè)工具,可以只添加引用的同時(shí)支持在 wasm 運(yùn)行的庫

"c:\Program Files\Mono\bin\mono" "f:/lindexi/mono/packager.exe" --copy=always --out=./publish Example.dll

注意上面的路徑,如果安裝的是 x86 的 mono 那么需要修改路徑為?c:\Program Files(x86)\Mono\bin\mono?此外需要將?f:/lindexi/mono/packager.exe?替換為你解壓縮的 mono 運(yùn)行時(shí)文件夾

執(zhí)行上面命令如果看到下面輸出,那么就是運(yùn)行成功

cp: Always - f:\temp\WpfApp1\YadernawcoLofeleabe\Example.dll -> ./publish\managed\Example.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\mscorlib.dll -> ./publish\managed\mscorlib.dll cp: Always - f:\lindexi\mono\framework\WebAssembly.Bindings.dll -> ./publish\managed\WebAssembly.Bindings.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\Facades\netstandard.dll -> ./publish\managed\netstandard.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.dll -> ./publish\managed\System.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\Mono.Security.dll -> ./publish\managed\Mono.Security.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.Xml.dll -> ./publish\managed\System.Xml.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.Numerics.dll -> ./publish\managed\System.Numerics.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.Core.dll -> ./publish\managed\System.Core.dll cp: Always - f:\lindexi\mono\framework\WebAssembly.Net.WebSockets.dll -> ./publish\managed\WebAssembly.Net.WebSockets.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\Facades\System.Memory.dll -> ./publish\managed\System.Memory.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.Data.dll -> ./publish\managed\System.Data.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.Transactions.dll -> ./publish\managed\System.Transactions.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.Data.DataSetExtensions.dll -> ./publish\managed\System.Data.DataSetExtensions.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\Facades\System.Drawing.Common.dll -> ./publish\managed\System.Drawing.Common.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.IO.Compression.dll -> ./publish\managed\System.IO.Compression.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.IO.Compression.FileSystem.dll -> ./publish\managed\System.IO.Compression.FileSystem.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.ComponentModel.Composition.dll -> ./publish\managed\System.ComponentModel.Composition.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.Net.Http.dll -> ./publish\managed\System.Net.Http.dll cp: Always - f:\lindexi\mono\framework\WebAssembly.Net.Http.dll -> ./publish\managed\WebAssembly.Net.Http.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.Runtime.Serialization.dll -> ./publish\managed\System.Runtime.Serialization.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.ServiceModel.Internals.dll -> ./publish\managed\System.ServiceModel.Internals.dll cp: Always - f:\lindexi\mono\wasm-bcl\wasm\System.Xml.Linq.dll -> ./publish\managed\System.Xml.Linq.dll

此時(shí)打開 Program.cs 所在的文件夾,可以看到文件夾包含了 publish 文件夾,這個(gè)文件夾里面的內(nèi)容就是 wasm 使用的文件了,而剛才編譯的 Example.dll 就放在 managed 文件夾里面

下一步就是如何在 html 中使用剛才編譯出來的 Excample.dll 文件了,這部分感謝前端的小智的協(xié)助

需要在 html 中引用 publish 文件夾下的?mono-config.js?和?runtime.js?和?dotnet.js?文件夾

<script type="text/javascript" src="./mono-config.js"></script><script type="text/javascript" src="./runtime.js"></script><script async type="text/javascript" src="./dotnet.js"></script>

接下來就是如何在 js 代碼調(diào)用 C# 編譯的 dll 了

通過?Module.mono_bind_static_method?可以將 js 的一個(gè)方法綁定到一個(gè)靜態(tài)的方法里面

Module.mono_bind_static_method("[Example] YadernawcoLofeleabe.Example:Hello");

使用格式是?Module.mono_bind_static_method("[dll文件名] 命名空間.類名:靜態(tài)方法");?如上面代碼

嘗試復(fù)制下面代碼放在 html 里面

<script type="text/javascript">let that = this;var App = {onClick: function () {that.output.value = "Please wait";that.output.value = that.execute("Ali");},init: function () {that.execute = Module.mono_bind_static_method("[Example] YadernawcoLofeleabe.Example:Hello");that.output = document.getElementById("output");that.button = document.getElementById("button");that.button.disabled = false;}}; </script>

如果你的 dll 命名和命名空間和我不相同,那么請(qǐng)自己修改

接下來就是添加簡(jiǎn)單的界面了

<!DOCTYPE doctype html> <html lang="en"><head><!-- Required meta tags --><meta charset="utf-8"><meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport"><!-- Bootstrap CSS --><link crossorigin="anonymous" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/css/bootstrap.min.css" integrity="sha384-SI27wrMjH3ZZ89r4o+fGIJtnzkAnFs3E4qz9DIYioCQ5l9Rd/7UAa8DHcaL8jkWt" rel="stylesheet"><title>Hello, Mono WASM!</title></link></meta></meta></head><body><div class="container"><h1>Hello, world!</h1><form><div class="form-group"><label for="output">Output from C#:</label><textarea class="form-control" id="output" rows="10"></textarea></div><div class="form-group"><button class="btn btn-primary" id="button" onclick="App.onClick" type="button">Run WASM, Run!</button></div></form></div><script type="text/javascript">let that = this;var App = {onClick: function () {that.output.value = "Please wait";that.output.value = that.execute("Ali");},init: function () {that.execute = Module.mono_bind_static_method("[Example] YadernawcoLofeleabe.Example:Hello");that.output = document.getElementById("output");that.button = document.getElementById("button");that.button.disabled = false;}}; document.getElementById("button").addEventListener("click", App.onClick);document.body.addEventListener("load", App.init);</script><script src="./mono-config.js" type="text/javascript"></script><script src="./runtime.js" type="text/javascript"></script><script async="" src="./dotnet.js" type="text/javascript"></script></body> </html>

嘗試開啟一個(gè)靜態(tài)的 HTTP 服務(wù)器,然后在瀏覽器訪問這個(gè) html 文件,注意將 dll 文件設(shè)置用戶可下載,這樣就完成了。例子可以訪問https://0x414c49.github.io/wasm-example/index.html?這里有所有的文件

其實(shí)我在入門翻了車,多謝下面大佬的博客,本文大部分代碼都是抄下面博客

Run C# natively in the browser through the web assembly via mono-wasm:?https://medium.com/m/global-identity?redirectUrl=https%3A%2F%2Fitnext.io%2Frun-c-natively-in-the-browser-through-the-web-assembly-via-mono-wasm-60f3d55dd05a?

看到這里小伙伴想到了什么?沒錯(cuò),微軟 Blazor 就是用這個(gè)原理,用 C# 寫前端

總結(jié)

以上是生活随笔為你收集整理的dotnet 将C#编译为wasm让前端html使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。