Lua教程(二十) Lua呼叫C函式

2021-08-16 14:10:16 字數 1572 閱讀 5238

lua可以呼叫c函式的能力將極大的提高lua的可擴充套件性和可用性。對於有些和作業系統相關的功能,或者是對效率要求較高的模組,我們完全可以通過c函式來實現,之後再通過lua呼叫指定的c函式。對於那些可被lua呼叫的c函式而言,其介面必須遵循lua要求的形式,即typedef int (*lua_cfunction)(lua_state* l)。簡單說明一下,該函式型別僅僅包含乙個表示lua環境的指標作為其唯一的引數,實現者可以通過該指標進一步獲取lua**中實際傳入的引數。返回值是整型,表示該c函式將返回給lua**的返回值數量,如果沒有返回值,則return 0即可。需要說明的是,c函式無法直接將真正的返回值返回給lua**,而是通過虛擬棧來傳遞lua**和c函式之間的呼叫引數和返回值的。這裡我們將介紹兩種lua呼叫c函式的規則。

1. c函式作為應用程式的一部分。

#include

#include

#include

#include

#include

//待lua呼叫的c註冊函式。

static int add2(lua_state* l)

//另乙個待lua呼叫的c註冊函式。

static int sub2(lua_state* l)

const char* testfunc = "print(add2(1.0,2.0)) print(sub2(20.1,19))";

int main()

extern "c" int sub(lua_state* l)

//lual_reg結構體的第乙個欄位為字串,在註冊時用於通知lua該函式的名字。

//第乙個欄位為c函式指標。

//結構體陣列中的最後乙個元素的兩個欄位均為null,用於提示lua註冊函式已經到達陣列的末尾。

static lual_reg mylibs = ,, 

};//該c庫的唯一入口函式。其函式簽名等同於上面的註冊函式。見如下幾點說明:

//1. 我們可以將該函式簡單的理解為模組的工廠函式。

//2. 其函式名必須為luaopen_***,其中***表示library名稱。lua**require "***"需要與之對應。

//3. 在lual_register的呼叫中,其第乙個字串引數為模組名"***",第二個引數為待註冊函式的陣列。

//4. 需要強調的是,所有需要用到"***"的**,不論c還是lua,都必須保持一致,這是lua的約定,

//   否則將無法呼叫。

extern "c" __declspec(dllexport)

int luaopen_mytestlib(lua_state* l) 

{const char* libname = "mytestlib";

lual_register(l,libname,mylibs);

return 1;

見如下lua**:

require "mytestlib"  --指定包名稱

--在呼叫時,必須是package.function

print(mytestlib.add(1.0,2.0))

print(mytestlib.sub(20.1,19))

lua呼叫c函式

最近在進入lua程式設計的狀態,一度令我困惑的是,lua提供的功能少的可憐,跟自備電池的python相比,可說是簡陋了。連table的列印,都需要自己實現,也因此有了一打的第三方方案。後來我想明白了,以lua和c如此緊密的關係,只需要建立lua的binding,那麼豐富而效能強大的c庫資源完全可以為...

lua呼叫c函式

lua可以呼叫c函式的能力將極大的提高lua的可擴充套件性和可用性。對於有些和作業系統相關的功能,或者是對效率要求較高的模組,我們完全可以通過c函式來實現,之後再通過lua呼叫指定的c函式。對於那些可被lua呼叫的c函式而言,其介面必須遵循lua要求的形式,即 typedef int lua cfu...

lua呼叫C函式

lua採取的是利用棧進行互動,利用各種lua push 將不同的值壓入棧中,然後呼叫lua指令碼時自然會退棧取出引數執行,對於lua的虛擬機器來說,就像是發生了一次正常的函式呼叫。這裡採用的棧是lua棧,因為若是c棧的話呼叫lua的c api就會出錯了。需要注意的是,lua棧狀態需要自己進行維護,若...