linux下Lua呼叫C函式

2021-07-16 13:47:18 字數 1861 閱讀 8799

這篇文章

的基礎上編寫的,由於原文章採用的是lua-5.2以下的版本,但是lua-5.2的版本進行了很大的改動,導致之前的很多函式不能再使用。本文就解決了採用lua-5.3.0中的api函式之後,原文章中**存在的一些問題。

這裡只講原文章中提到的第二種方法c函式庫成為lua的模組,以實現lua呼叫c函式,另外一種方法可以參考原文章。

c函式庫成為lua的模組其實就是將包含c函式的**生成庫檔案,如linux的so。將其放至相應目錄,以便於lua解析器可以正確定位到它們。下面以**進行解釋。

以下是test.c的**:

#include#include#include#include#includeint add(lua_state* l)   //去掉了原**中的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_setfuncs的呼叫中,其第二個引數為待註冊函式的陣列。

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

//   否則將無法呼叫。

int luaopen_mytestlib(lua_state* l)

在test.c中去掉了源**中的extern 「c」,如若不去掉會報錯:/usr/local/include/lua.hpp:5:8: error: expected identifier or 『(』 before string constant extern "c" 

以下是test.lua的**:

local mylib = require("mytestlib")  --對應於teste.c中的包名      

print(mylib.add(1.0,2.0))

print(mylib.sub(20.1,19))

在原文章的test.lua**中沒有定義變數mylib,是直接requier("mytestlib"),再用mytestlib.add去呼叫函式c中的函式add。反正我用原**執行的時候會報錯,在網上找了很久這個問題,最終改為了現在的**。

原文章**的報錯資訊為:lua: test.lua:4: attempt to index a nil value (global 'mytestlib')

至此**編寫部分就這些,這裡再記錄一下這段**的編譯鏈結過程,使可以看到**的執行結果,以證明**的正確性。

將test.c編譯成.o檔案:gcc -c -fpic -o test.o test.c

將test.o編譯成.so檔案:gcc -shared -o mytestlib.so test.o

執行test.lua**:lua test.lua

編譯鏈結之後資料夾中的檔案如下圖所示:

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棧狀態需要自己進行維護,若...