lua(xlua)基礎知識點記錄二

1. 關于lua函數傳參參數

在lua中給function傳遞參數的時候一般分為兩種情況:值傳遞和引用傳遞

值傳遞:

值傳遞:數字、字符串、布爾值、nil等基本類型通過值傳遞。函數內部接收的是外部變量的副本,修改副本不會影響原始變量。
雖然我們都知道字符串是引用類型存儲的數據,但是在函數傳參的時候傳遞的是指向字符串內存地址的指針值?(即引用的副本),而非原始變量的引用本身

function Test(n)n = n + 1
end
local a = 1
Test(a)
print("輸出a:"..a)
-- 結果a仍然是1

引用傳遞:

?表(table)和函數如果當作函數的參數傳遞時,傳遞的時指向具體變量的地址的副本,記住時副本!!可以理解成表本身就是一個指針,把這個指針當作參數傳遞給函數時,會重新生成一個指針,并且把該變量的指針地址值復制給新生成的指針。所以這種情況下,如果直接操作(增刪)都可以正常影響指向的變量數據。但是如果時賦值操作,那么就會修改傳遞過去的副本指向的內容。

function Test1(t)t.a = 1
endfunction Test2(t)t = {a = 15,b =3}
endfunction Test3(t)t = nil
endlocal t = {a = 10, b = 2}Test1(t)
print("t.a:"..t.a.." t.b:"..t.b)
Test2(t)
print("t.a:"..t.a.." t.b:"..t.b)
Test3(t)
print("t.a:"..t.a.." t.b:"..t.b)

上述代碼三次的輸出都是: t.a:1 t.b:2,
.
調用Test1的時候直接修改了引用指向的內容,所以修改生效。此時外部的t.a = 1。
.
調用Test2的時候直接把引用副本指向了另一個新表的內存,那么這時候函數內部的t已經和外部傳進去的t沒有關系了,所以怎么修改都不會對外部的t造成影響。
.
調用Test3的時候和Test2一樣,把引用副本指向了空,同樣和外部的t沒有關聯關系了,所以外部t不受影響。

2. 關于c#和lua相互引用(xlua版)

userdata

我們都知道lua中有一種數據類型-userdata
.
userdata 是 Lua 為存儲 C/C++ 等外部語言數據而設計的特殊類型,提供了一塊原始內存區域,可直接存放結構體、指針、文件句柄等外部對象。它允許 Lua 通過指針或內存塊直接操作外部環境的數據,是 Lua 與 C/C++ 交互的核心機制。例如,C 中定義的 struct People 可通過 userdata 傳遞給 Lua 腳本使用.
.
所以一個語言只要可以和c/c++交互,那么就可以通過userdata和lua交互,這也是c#和lua交互的底層原理。
.

xlua中的c#和lua交互

在xlua中,c#和lua的交互都是通過c這個他們兩種語言都能到的媒介實現的。
大致流程如下:

lua call c#

lua調用c# -> 調用c -> 操作虛擬棧對參數壓棧 -> 調用c#wrap函數/反射查找函數 ->
把lua函數參數轉換成c#類型 -> 完成調用

c# call lua

c#調用lua -> c#調用c函數 -> 通過capi找到lua函數(lua_getglobal) -> c#數據轉成lua數據(lua_pushinteger) ->
通過capi調用lua函數(lua_pcall)

xlua中c#和lua相互引用

在xlua框架中,可以很方便的在lua中持有C#的對象變量并使用,反之一樣。

lua持有c#對象:

通過上述的userdata了解,我們可以大致了解到,其實c#的變量在lua中是以userdata類型的數據存儲的。
事實上在lua中從來沒有真正的持有c#的真正變量。

?C#對象在Lua中的表示

在xLua中,C#對象傳遞到Lua時會被封裝為userdata類型。這個userdata并不直接存儲C#對象本身,而是存儲一個唯一標識符(objId)?,用于關聯C#端的實際對象

引用關系的管理(lua持有#)

但是我們也知道c#的gc是并不清楚lua環境中該userdata的引用情況的,如果直接不管lua中是否引用只要c#段就沒有引用就GC掉顯然不符合我們的需求。所以xlua中設計了ObjectTranslator.cs。
ObjectTranslator通過ObjectPool和ReverseMap維護對象與objId的映射,確保C#對象不被GC回收(只要Lua仍持有userdata)
而在lua中,userdata是被存放在弱引用表中的,只要lua中沒有強引用該對象的存在,那么該userdata就可以被lua的gc回收掉,防止lua一致持有著objid而c#無法回收對應對象。

lua對象在c#中的表示:

所有Lua對象在C#中通過LuaBase基類管理,其構造函數調用luaL_ref在Lua注冊表中創建引用,析構時調用luaL_unref釋放

其實講了那么多,就是為了理解如下代碼:

public class Main{public class TestClass{}public static TestClass MyClassTest;public static TestClass CreateTestClass(){if (MyClassTest == null) MyClassTest = new TestClass();return MyClassTest;}public static void DestroyTestClass(){MyClassTest = null;}
}
local myClass,myClass2,myClass3local function Execute()myClass = CS.Main.CreateTestClass()myClass2 = CS.Main.MyClassTestmyClass3 = myClass2myClass2 = nilcollectgarbage("collect")CS.System.GC.Collect()CS.Main.DestroyTestClass()collectgarbage("collect")CS.System.GC.Collect()
endpcall(Execute)

由上面講述我們可以知道,一個c#變量在lua中的話,兩端是各自持有各自的類型(userdata和TestClass),上述lua代碼中的myClass,myClass2和myClass3就是對應的userdata。
.
即使myClass2 = nil后,myClass3和myClass仍然持有該userdata,所以第一次執行雙方gc,只會回收掉myClass2。myClass3和myClass以及c#段的MyClassTest都沒收影響。
.
那么再來看CS.Main.DestroyMyClass() 這句之后c#側的MyClassTest引用被置空,注意只是引用實際變量還被lua持有,所以即使執行了C#的gc,真正的對象仍不會被回收掉,因為myClass 和myClass3仍然還存在著并且持有著。
.
那么這時候如何回收掉TestClass對應的數據,只需要再加上
myClass2 = nil
myClass = nil
collectgarbage("collect")
CS.System.GC.Collect()
這樣的話lua測得強引用也沒了,都可以被回收了

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/915386.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/915386.shtml
英文地址,請注明出處:http://en.pswp.cn/news/915386.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

分治算法---歸并

1、排序數組 class Solution {vector<int> tmp; public:vector<int> sortArray(vector<int>& nums) {tmp.resize(nums.size());mergeSort(nums,0,nums.size() - 1);return nums;}void mergeSort(vector<int>& nums, int left , int right){if…

《計算機網絡》實驗報告三 UDP協議分析

目 錄 1、實驗目的 2、實驗環境 3、實驗內容 3.1 DNS查詢UDP數據分析 3.2 QQ通信UDP數據分析 4、實驗結果與分析 4.1 DNS查詢UDP數據分析 4.2 QQ通信UDP數據分析 4.3 根據捕獲的數據包&#xff0c;分析UDP的報文結構&#xff0c;將UDP協議中個字段名&#xff0c;字段…

Mysql 學習總結(90)—— Mysql 8.0 25 條性能優化實戰指南

1. 內存配置優化 # my.cnf 關鍵內存參數 innodb_buffer_pool_size = 8G # 建議設置為物理內存的70-80% innodb_log_buffer_size = 64M # 日志緩沖區大小 query_cache_size = 0 # MySQL 8.0已移除,確保關閉 tmp_table_size = 256M # 臨時表大小 max_…

嵌入式通信DQ單總線協議及UART(一)

文章目錄一、DS18B20--DQ單總線1.1 單總線時序結構分析1.1.1 初始化&#xff1a;1.1.2 發送一位1.1.3 接收一位1.1.5 發送字節1.1.6 操作流程1.1.7 數據幀的理解1.1.8 數據幀的理解二、UART2.1 同步通信和異步通信2.2 雙工通信2.3 串行通信常用數據校驗方式2.3.1 奇偶檢驗2.3.2…

2025年SEVC SCI2區,利用增強粒子群算法(MR-MPSO)優化MapReduce效率和降低復雜性,深度解析+性能實測

目錄1.摘要2.MapReduce-Modified Particle Swarm Optimization (MR-MPSO)3.結果展示4.參考文獻5.算法輔導應用定制讀者交流1.摘要 大數據的迅猛增長帶來了嚴峻的數據管理挑戰&#xff0c;尤其是在數據分布不均的龐大數據庫中。由于這種不匹配&#xff0c;傳統軟件系統的效率大…

10-day07文本分類

文本分類使用場景文本分類任務 文本分類-機器學習貝葉斯算法應用在NLP中的應用 用貝葉斯公式處理文本分類任務 一個合理假設&#xff1a; 文本屬于哪個類別&#xff0c;與文本中包含哪些詞相關 任務&#xff1a; 知道文本中有哪些詞&#xff0c;預測文本屬于某類別的概率 貝葉斯…

Apache SeaTunnel詳解與部署(最新版本2.3.11)

目錄 一、概述 1.1、軟件介紹 1.2、解決問題? 1.3、軟件特性? 1.4、使用用戶 1.5、產品對比 二、架構 2.1、運行流程 2.2、連接器? 2.3、引擎 2.3.1、設計理念 2.3.2、集群管理? 2.3.3、核心功能? 2.3.4、引擎對比 三、軟件部署 3.1、Docker部署 3.2、發…

pytorch | minist手寫數據集

一、神經網絡神經網絡&#xff08;Neural Network&#xff09;是一種受生物神經系統&#xff08;尤其是大腦神經元連接方式&#xff09;啟發的機器學習模型&#xff0c;是深度學習的核心基礎。它通過模擬大量 “人工神經元” 的互聯結構&#xff0c;學習數據中的復雜模式和規律…

[C/C++安全編程]_[中級]_[如何避免出現野指針]

場景 在Rust里不會出現野指針的情況&#xff0c;那么在C里能避免嗎&#xff1f; 說明 野指針是指指向無效內存地址的指針&#xff0c;訪問它會導致未定義行為&#xff0c;可能引發程序崩潰、數據損壞或安全漏洞。它是 C/C 等手動內存管理語言中的常見錯誤&#xff0c;而 Rust…

機器學習基礎:從數據到智能的入門指南

一、何謂機器學習? 在我們的日常生活中&#xff0c;機器學習的身影無處不在。當你打開購物軟件&#xff0c;它總能精準推薦你可能喜歡的商品&#xff1b;當你解鎖手機&#xff0c;人臉識別瞬間完成&#xff1b;當你使用語音助手&#xff0c;它能準確理解你的指令。這些背后&a…

steam游戲搬磚項目超完整版實操分享

大家好&#xff0c;我是阿陽&#xff0c;今天再次最詳細的給大家綜合全面的分析講解下steam搬磚&#xff0c;可以點擊后面跳轉往期文章了再次解下阿陽網客&#xff1a;關于steam游戲搬磚項目&#xff0c;我想說&#xff01;最早是21年5月份公開朋友圈&#xff0c;初次接觸是在2…

vue2 面試題及詳細答案150道(21 - 40)

《前后端面試題》專欄集合了前后端各個知識模塊的面試題&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

原生前端JavaScript/CSS與現代框架(Vue、React)的聯系與區別(詳細版)

原生前端JavaScript/CSS與現代框架&#xff08;Vue、React&#xff09;的聯系與區別&#xff0c;以及運行環境和條件 目錄 引言原生前端技術概述 JavaScript基礎CSS基礎 現代框架概述 Vue.jsReact 聯系與相似性主要區別對比運行環境和條件選擇建議總結 引言 在現代Web開發中&…

基于機器視覺的邁克耳孫干涉環自動計數系統設計與實現

基于機器視覺的邁克耳孫干涉環自動計數系統設計與實現 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到網站。 摘要 本文設計并實現了一種基于機器視覺的邁克耳孫干涉環自動計數系統。該系統…

設計模式筆記(1)簡單工廠模式

最近在看程杰的《大話設計模式》&#xff0c;在這里做一點筆記。 書中主要有兩個角色&#xff1a; 小菜&#xff1a;初學者&#xff0c;學生&#xff1b; 大鳥&#xff1a;小菜表哥&#xff0c;大佬。 也按圖中的對話形式 01 簡單工廠模式 要求&#xff1a;使用c、Java、C#或VB…

Vue3 學習教程,從入門到精通,Vue 3 聲明式渲染語法指南(10)

Vue 3 聲明式渲染語法指南 本文將詳細介紹 Vue 3 中的聲明式渲染語法&#xff0c;涵蓋所有核心概念&#xff0c;并通過一個完整的案例代碼進行演示。案例代碼中包含詳細注釋&#xff0c;幫助初學者更好地理解每個部分的功能和用法。 目錄 簡介聲明式渲染基礎 文本插值屬性綁…

React hooks——useReducer

一、簡介useReducer 是 React 提供的一個高級 Hook&#xff0c;用于管理復雜的狀態邏輯。它類似于 Redux 中的 reducer 模式&#xff0c;適合處理包含多個子值、依賴前一個狀態或邏輯復雜的狀態更新場景。與 useState 相比&#xff0c;useReducer 提供更結構化的狀態管理方式。…

SEO中關于關鍵詞分類與布局的方法有那些

前邊我們說到關鍵詞挖掘肯定很重要&#xff0c;但如何把挖掘出來的關鍵詞用好更為重要&#xff0c;下邊我們就來說說很多seo剛入行的朋友比較頭疼的關鍵詞分類問題&#xff0c;為了更直觀的感受搭配了表格&#xff0c;希望可以給大家一些幫助!SEO優化之關鍵詞分類?挖掘出的關鍵…

考研最高效的準備工作是什么

從性價比的角度來說&#xff0c;考研最高效的準備工作是什么呢&#xff1f; 其實就是“卷成績”。 卷學校中各門課程的成績&#xff0c;卷考研必考的數學、英語、政治和專業課的成績。 因為現階段的考研&#xff0c;最看重的仍然是你的成績&#xff0c;特別是初試成績。 有了…

【Linux】基于Ollama和Streamlit快速部署聊天大模型

1.環境準備 1.1 安裝Streamlit 在安裝Streamlit之前&#xff0c;請確保您的系統中已經正確安裝了Python和pip。您可以在終端或命令行中運行以下命令來驗證它們是否已安裝 python --version pip --version一旦您已經準備好環境&#xff0c;現在可以使用pip來安裝Streamlit了。…