C語言模塊回調(diào)Lua函數(shù)的兩種方法
lua和C通過虛擬棧這種交互方式簡單而又可靠,缺點就是C做棧平衡稍微會多寫一點代碼。 今天分享學(xué)到的C模塊回調(diào)Lua函數(shù)的兩種方法,都是炒冷飯,大俠勿噴。
1. C保存函數(shù)對象
C模塊可以通過注冊表保存Lua里面的對象,等適當(dāng)時候取出再調(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中,然后返回一個索引(目測是數(shù)組的index)。 lua_rawgeti把之前保存的function對象取出,再由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);
}
該方法的缺點就是如果C模塊獨立編寫,方法名就不太靈活。 用這種方法一般會在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中__index和__newindex之間的沉默與合作
這篇文章主要介紹了Lua中__index和__newindex之間的沉默與合作,本文著重講解了__index和__newindex之間的聯(lián)系,需要的朋友可以參考下2014-09-09Lua編程示例(一):select、debug、可變參數(shù)、table操作、error
這篇文章主要介紹了Lua編程示例(一):select、debug、可變參數(shù)、table操作、error,本文直接給出代碼實例,需要的朋友可以參考下2015-07-07