最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#?NLua?Winform實(shí)現(xiàn)熱更新的項(xiàng)目實(shí)踐

 更新時(shí)間:2025年11月07日 11:34:18   作者:熊思宇  
本文介紹了在.NET應(yīng)用中使用NLua庫嵌入Lua腳本,實(shí)現(xiàn)動(dòng)態(tài)邏輯和熱更新功能,包括創(chuàng)建項(xiàng)目、設(shè)置公共數(shù)據(jù)、Lua腳本交互以及熱更新的具體實(shí)現(xiàn)步驟,感興趣的可以了解一下

一、概述

NLua 是一個(gè)用于 .NET 平臺(tái)的 Lua 腳本綁定庫。它允許在 C# 代碼中嵌入 Lua 腳本,并允許兩者之間進(jìn)行交互。NLua 的主要特點(diǎn)包括:

  1. 輕量級(jí):NLua 是一個(gè)輕量級(jí)的庫,易于集成到現(xiàn)有的 .NET 項(xiàng)目中。
  2. 動(dòng)態(tài)類型:Lua 是動(dòng)態(tài)類型的語言,這意味著變量的類型可以在運(yùn)行時(shí)改變。
  3. 靈活的綁定:NLua 提供了靈活的綁定機(jī)制,使得 C# 和 Lua 之間的數(shù)據(jù)交互變得簡(jiǎn)單。
  4. 豐富的 API:NLua 提供了豐富的 API,以便在 Lua 腳本中調(diào)用 .NET 的類和方法。
  5. 調(diào)試支持:NLua 支持調(diào)試功能,方便開發(fā)者在 Lua 腳本中設(shè)置斷點(diǎn)、單步執(zhí)行等操作。
  6. 社區(qū)支持:NLua 有一個(gè)活躍的社區(qū),為開發(fā)者提供了一個(gè)交流和尋求幫助的平臺(tái)。

使用 NLua,你可以在 .NET 應(yīng)用中輕松地嵌入 Lua 腳本,從而實(shí)現(xiàn)動(dòng)態(tài)邏輯、配置管理、插件系統(tǒng)等功能。通過 NLua,你可以利用 Lua 的靈活性和易用性,同時(shí)保持 .NET 的強(qiáng)大功能和性能。

NLua 支持 UWP、Windows、Linux、Mac、iOS、Android 平臺(tái)。

NLua 源碼和示例 Github 地址

GitHub - NLua/NLua: Bridge between Lua and the .NET.

二、創(chuàng)建項(xiàng)目

創(chuàng)建一個(gè) .NET Framework  Winform 項(xiàng)目,這里我用的版本是 4.8.1,取名叫 NLuaDemo,在 NuGet 中安裝 NLua 包。

winform 界面設(shè)計(jì)如下:

為了先看看 NLua 到底有沒有效果,先做一個(gè)小案例,讓你先熟悉一下 NLua 框架,在后面的案例中,會(huì)有完整的熱更新方式展示。

需求:用 Lua 腳本來改變 Winform 界面中的抽獎(jiǎng)人數(shù),數(shù)量隨意。

本章節(jié)非重點(diǎn),可以直接看第三章節(jié)

1.添加一個(gè)類 PublicData ,這個(gè)類用來保存公共數(shù)據(jù)(在第三節(jié)的案例中,PublicData 這個(gè)類將不再使用)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public class PublicData
{
    public static NLuaDemo.Form1 Form1s { get; set; }
}

我將 From1 保存在這里,主要是為了方便后面 Lua 調(diào)用,在實(shí)際工作中,最好還是不要這么寫

2.將 Form1.Designer.cs 中的控件設(shè)置為 public,以便讓 Lua 能直接調(diào)用 winform 控件。

3.將 Program 類改為如下,在第三節(jié)的案例中,這里還是會(huì)恢復(fù)默認(rèn)的代碼,這里只是演示,這并不是一個(gè)好的寫法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NLuaDemo
{
    internal static class Program
    {
        /// <summary>
        /// 應(yīng)用程序的主入口點(diǎn)。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            PublicData.Form1s = new Form1();
            Application.Run(PublicData.Form1s);
        }
    }
}

4.Form1 代碼如下(第三節(jié)案例中,代碼會(huì)不一樣)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NLua;

namespace NLuaDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private Lua Luas = new Lua();
        //lua 腳本的地址
        private string LuaPath;

        private void Form1_Load(object sender, EventArgs e)
        {
            Luas.State.Encoding = Encoding.UTF8;
            LuaPath = $"{Application.StartupPath}\\main.lua";
            LoadLua();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Luas.Close();
        }

        //熱重載
        private void Button_HotUpdate_Click(object sender, EventArgs e)
        {
            Luas.DoString("update()");
        }

        private void LoadLua()
        {
            if (File.Exists(LuaPath))
            {
                Luas.LoadCLRPackage();
                Luas.DoFile(LuaPath);
                Luas["form1s"] = PublicData.Form1s;
            }
        }
    }
}

5.在項(xiàng)目的 Debug 目錄中,新建一個(gè) main.lua 文件,加入下面代碼

form1s = {};

function update()
    form1s.Label_RaffleNumber.Text = "抽獎(jiǎng)人數(shù):100" ;
end

完成了上面的工作,現(xiàn)在可以開始測(cè)試了

可以看到,Lua 腳本確實(shí)改變了 winform 界面的數(shù)據(jù)。

這里為什么不把邏輯直接寫在 main.lua 中呢?

form1s = {};

form1s.Label_RaffleNumber.Text = "抽獎(jiǎng)人數(shù):100" ;

function update()
    form1s.Label_RaffleNumber.Text = "抽獎(jiǎng)人數(shù):100" ;
end

因?yàn)檫\(yùn)行后就會(huì)報(bào)錯(cuò):

由于 Lua 腳本在運(yùn)行后,會(huì)執(zhí)行所有的代碼,但是我們定義的 Lua 全局變量此時(shí)還沒有賦值,直接運(yùn)行當(dāng)然報(bào)錯(cuò)了,于是我將熱更新內(nèi)容寫入到 lua 腳本中的 update 方法中,等 C# 這邊初始化完成后,調(diào)用 update 方法就不會(huì)有問題了。

另外還有一種方法,使用 LoadFile 方法,我試了一下,沒有效果,可能是我用法不對(duì)

LuaFunction luaFunction = Luas.LoadFile("C:\\test.lua");

有興趣的朋友可以去試試,有好的建議歡迎留言評(píng)論。

三、實(shí)現(xiàn) Lua 熱更新

在上面的案例中,我們是把 Form1 賦值給了 lua 腳本中的 form1s 這個(gè)變量(也可以叫表單),其實(shí)還可以這么寫:

private void LoadLua()
{
    if (File.Exists(LuaPath))
    {
        Luas.LoadCLRPackage();
        Luas.DoFile(LuaPath);
        Luas["this"] = this;
    }
}

但是這種用法在 Lua 腳本用會(huì)有錯(cuò)誤,在 Visual Studio Code 中搭建好 Lua 開發(fā)環(huán)境,就會(huì)看到提示:未定義的全局變量 “this”

這個(gè)不用管它,lua 腳本只要在 C# 項(xiàng)目中運(yùn)行不報(bào)錯(cuò)就行了。

這里的寫法改變后,上一個(gè) demo 中代碼也要改改了。

1.Program 類恢復(fù)默認(rèn)的寫法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NLuaDemo
{
    internal static class Program
    {
        /// <summary>
        /// 應(yīng)用程序的主入口點(diǎn)。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            //PublicData.Form1s = new Form1();
            //Application.Run(PublicData.Form1s);
            Application.Run(new Form1());
        }
    }
}

2.PublicData 類可以刪掉,或者注釋所有的代碼,現(xiàn)在用不上了。

另一個(gè),Lua 調(diào)用 C# 方法,要用英文的冒號(hào)去調(diào)用方法,而不是像 C# 一樣用點(diǎn)去調(diào)用,這個(gè)在 Unity3d 中 XLua 等熱更新框架是同樣的用法,具體用法可以參考下面 main.lua 代碼。

--import("System")
--import('System.Windows.Forms')
--import("System.Threading");

--form1s = {};

--獎(jiǎng)品
prize = {"手機(jī)", "電腦", "耳機(jī)", "鼠標(biāo)", "鍵盤", "充電寶"}
--抽獎(jiǎng)人
participant = {"張三", "李四", "老王", "狗蛋", "鐵剩"}

--熱重載
function update()
    this:Print("抽獎(jiǎng)人 長(zhǎng)度是:" .. #participant)
    this.Label_RaffleNumber.Text = "抽獎(jiǎng)人數(shù):" .. #participant
    this.Label_PrizesNum.Text = "獎(jiǎng)品數(shù):" .. #prize

    --獎(jiǎng)品下拉框
    this.ComboBox_Prize.Items:Clear()
    for i,item in ipairs(prize) do
        this.ComboBox_Prize.Items:Add(item)
    end
    this.ComboBox_Prize.SelectedIndex = 0

    --抽獎(jiǎng)人下拉框
    this.ComboBox_LotteryGiver.Items:Clear();
    for i,item in ipairs(participant) do
        this.ComboBox_LotteryGiver.Items:Add(item);
    end   
    this.ComboBox_LotteryGiver.SelectedIndex = 0
end

--抽獎(jiǎng)按鈕
function raffle()
    --隨機(jī)獎(jiǎng)品
    local prizeIndex = math.random(1, #prize) 
    local prize = prize[prizeIndex] 

    --隨機(jī)抽獎(jiǎng)人
    local participantIndex = math.random(1, #participant) 
    local participant = participant[participantIndex] 

    local content = "抽獎(jiǎng)人:"..participant..",獲得獎(jiǎng)品:"..prize
    this:Print(content) 
end

注意上面 lua 腳本中的 Label_RaffleNumber,Label_PrizesNum,ComboBox_Prize 等關(guān)鍵字,這都是 winform 的控件,如果你用的不是我的源碼,winform 控件名和 lua 腳本中的也不一致,那么運(yùn)行就會(huì)報(bào)錯(cuò):

錯(cuò)誤:

當(dāng)前 demo 所有的控件名

winform 這個(gè)控制臺(tái)不知道怎么回事,lua 中打印用的 print 方法打印出來全是亂碼,但是 winform 控件使用 lua 腳本中的中文還是正常的。

后面我只能在 Form1 中添加一個(gè) Print 方法,這樣打印才是正常的。

Form1代碼:

using NLua;
using System;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace NLuaDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private Lua Luas = new Lua();
        //lua 腳本的地址
        private string LuaPath;

        private void Form1_Load(object sender, EventArgs e)
        {
            Luas.State.Encoding = Encoding.UTF8;
            LuaPath = $"{Application.StartupPath}\\main.lua";
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Luas.Close();
        }

        //熱重載 點(diǎn)擊事件
        private void Button_HotUpdate_Click(object sender, EventArgs e)
        {
            LoadLua();
            Luas.DoString("update()");
        }

        //抽獎(jiǎng) 點(diǎn)擊事件
        private void Button_Raffle_Click(object sender, EventArgs e)
        {
            Luas.DoString("raffle()");
        }

        //加載 lua 腳本
        private void LoadLua()
        {
            if (File.Exists(LuaPath))
            {
                Luas.LoadCLRPackage();
                Luas.DoFile(LuaPath);
                Luas["this"] = this;
            }
        }

        //lua 打印用的
        public void Print(string text)
        {
            Console.WriteLine(text);
        }
    }
}

運(yùn)行后,點(diǎn)擊 “熱重載” 按鈕,就會(huì)看到獎(jiǎng)品和抽獎(jiǎng)人都有那些內(nèi)容,這些都是由 lua 進(jìn)行賦值的。

點(diǎn)擊 “抽獎(jiǎng)” 按鈕,就可以看到當(dāng)前的中獎(jiǎng)人和獎(jiǎng)品

既然是熱更新,那我在運(yùn)行過程中改變代碼可以么?當(dāng)然可以!

我們把 lua 腳本中抽獎(jiǎng)人和獎(jiǎng)品表單刪除一部分,改完后記得保存,如下:

--獎(jiǎng)品
prize = {"手機(jī)", "電腦", "耳機(jī)", "鼠標(biāo)"}
--抽獎(jiǎng)人
participant = {"張三", "李四", "老王"}

再次點(diǎn)擊 “熱重載” 按鈕,這時(shí)界面就發(fā)生了一些變化

抽獎(jiǎng)人和獎(jiǎng)品都少了

NLua 其實(shí)還有很多其他的用法,這里就沒一一展示了。

到此這篇關(guān)于C# NLua Winform實(shí)現(xiàn)熱更新的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)C# NLua Winform 熱更新內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • unity實(shí)現(xiàn)鼠標(biāo)跟隨(ITween)

    unity實(shí)現(xiàn)鼠標(biāo)跟隨(ITween)

    這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)鼠標(biāo)跟隨,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • Visual Studio 中自定義代碼片段的方法

    Visual Studio 中自定義代碼片段的方法

    這篇文章主要介紹了Visual Studio 中自定義代碼片段的方法,本文分步驟通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • C#基于FTP協(xié)議的簡(jiǎn)易軟件自動(dòng)升級(jí)程序

    C#基于FTP協(xié)議的簡(jiǎn)易軟件自動(dòng)升級(jí)程序

    這篇文章主要為大家詳細(xì)介紹了C#基于FTP協(xié)議的簡(jiǎn)易軟件自動(dòng)升級(jí)程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • C#異常處理的技巧和方法

    C#異常處理的技巧和方法

    在本篇文章里小編給大家整理了關(guān)于C#異常處理的技巧和方法以及相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。
    2019-03-03
  • C#窗體傳值代碼方法

    C#窗體傳值代碼方法

    在本篇文章里小編給大家整理的是關(guān)于C#窗體傳值代碼內(nèi)容,需要的朋友們可以跟著學(xué)習(xí)參考下。
    2020-02-02
  • WPF彈出帶蒙板的消息框

    WPF彈出帶蒙板的消息框

    這篇文章主要為大家詳細(xì)介紹了WPF彈出帶蒙板的消息框,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • C#?9使用foreach擴(kuò)展的示例詳解

    C#?9使用foreach擴(kuò)展的示例詳解

    在?C#?9?中,foreach?循環(huán)可以使用擴(kuò)展方法。在本文中,我們將通過例子回顧?C#?9?中如何擴(kuò)展?foreach?循環(huán),感興趣的小伙伴可以了解一下
    2023-01-01
  • 在C#項(xiàng)目中調(diào)用C++編寫的動(dòng)態(tài)庫的三種方式

    在C#項(xiàng)目中調(diào)用C++編寫的動(dòng)態(tài)庫的三種方式

    這篇文章給大家介紹了三種方式詳解如何在C#項(xiàng)目中調(diào)用C++編寫的動(dòng)態(tài)庫,文中通過代碼示例給大家介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下
    2024-01-01
  • 基于Unity3D實(shí)現(xiàn)3D迷宮小游戲的示例代碼

    基于Unity3D實(shí)現(xiàn)3D迷宮小游戲的示例代碼

    迷宮游戲作為經(jīng)典的小游戲,一直深受大家的喜愛。本文小編將為大家詳細(xì)介紹一下如何用Unity實(shí)現(xiàn)一個(gè)3D版的迷宮小游戲,感興趣的可以動(dòng)手試一試
    2022-03-03
  • C# WPF實(shí)現(xiàn)讀取文件夾中的PDF并顯示其頁數(shù)的操作指南

    C# WPF實(shí)現(xiàn)讀取文件夾中的PDF并顯示其頁數(shù)的操作指南

    文章介紹了利用WPF和AI工具Gemini開發(fā)PDF整理工具的過程,采用iText處理PDF、NPOI導(dǎo)出Excel,結(jié)合MVVM模式實(shí)現(xiàn)UI與邏輯分離,并解決轉(zhuǎn)換器錯(cuò)誤問題,最終完成文件信息展示與批量處理功能,需要的朋友可以參考下
    2025-09-09

最新評(píng)論

海城市| 潼关县| 桂平市| 黔西| 铅山县| 邵武市| 乳山市| 麻栗坡县| 海南省| 灵川县| 卢氏县| 吴忠市| 泾源县| 冷水江市| 右玉县| 平乐县| 成武县| 桃园市| 林周县| 阿瓦提县| 柳林县| 拜泉县| 湘潭县| 竹北市| 方山县| 恩施市| 石景山区| 昭通市| 周宁县| 汤原县| 尼玛县| 永善县| 郎溪县| 常州市| 祁东县| 新野县| 台山市| 洛阳市| 汉阴县| 湖南省| 凤阳县|