C語言模塊回調(diào)Lua函數(shù)的兩種方法
lua和C通過虛擬棧這種交互方式簡單而又可靠,缺點(diǎn)就是C做棧平衡稍微會(huì)多寫一點(diǎn)代碼。 今天分享學(xué)到的C模塊回調(diào)Lua函數(shù)的兩種方法,都是炒冷飯,大俠勿噴。
1. C保存函數(shù)對(duì)象
C模塊可以通過注冊(cè)表保存Lua里面的對(duì)象,等適當(dāng)時(shí)候取出再調(diào)用即可。
static int lua_callback = LUA_REFNIL;
static int setnotify(lua_State *L)
{
lua_callback = luaL_ref(L, LUA_REGISTRYINDEX);
return 0;
}
static int testnotify(lua_State *L)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, lua_callback);
lua_call(L, 0, 0);
}
luaL_ref把棧頂?shù)闹等〕?,放到指定的tabel中,然后返回一個(gè)索引(目測(cè)是數(shù)組的index)。 lua_rawgeti把之前保存的function對(duì)象取出,再由lua_call調(diào)用。
function callback( )
print "Callback"
end
cb.setnotify(callback)
cb.testnotify()
2. C訪問Lua全局環(huán)境
第二種方法更簡便,C直接調(diào)用Lua中的函數(shù),就像Lua調(diào)用C一樣
static int testenv(lua_State *L)
{
lua_getglobal(L, "defcallback");
lua_call(L, 0, 0);
}
該方法的缺點(diǎn)就是如果C模塊獨(dú)立編寫,方法名就不太靈活。 用這種方法一般會(huì)在Lua端再封裝一層,以隔離全局環(huán)境。
3. 完整例子
cb.c
#include <stdio.h>
#include <stdlib.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static int lua_callback = LUA_REFNIL;
static int setnotify(lua_State *L)
{
lua_callback = luaL_ref(L, LUA_REGISTRYINDEX);
return 0;
}
static int testnotify(lua_State *L)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, lua_callback);
lua_call(L, 0, 0);
}
static int testenv(lua_State *L)
{
lua_getglobal(L, "defcallback");
lua_call(L, 0, 0);
}
static const luaL_Reg cblib[] = {
{"setnotify", setnotify},
{"testnotify", testnotify},
{"testenv", testenv},
{NULL, NULL}
};
int luaopen_cb(lua_State *L)
{
luaL_register(L, "cb", cblib);
return 1;
}
test.lua
require("cb")
function callback( )
print "Callback"
end
function defcallback()
print "Predef callback"
end
cb.setnotify(callback)
cb.testnotify()
print "Done"
cb.testenv()
相關(guān)文章
lua閉包的理解以及表與函數(shù)的幾種表達(dá)方法
本文首先通過具體的例子講解了Lua中閉包的概念,然后總結(jié)了閉包的應(yīng)用場(chǎng)合,最后探討了Lua中閉包的實(shí)現(xiàn)原理,以及l(fā)ua中表與函數(shù)的3種表達(dá)方式的匯總2015-08-08
Lua判斷變量是否為數(shù)字、字符串是否可以轉(zhuǎn)換為數(shù)字等

