原生实现C#和Lua相互调用-Unity3D可用
三、C#与Lua的相互调用举例
1. C#中创建Lua环境
IntPtr L = LuaDll.luaL_newstate(); LuaDll.luaL_openlibs(L);
2. 加载Lua代码并执行,调用Lua的函数及向Lua传递参数
var data = Resources.Load<TextAsset>(lua_file); int rc = LuaDll.luaL_loadbuffer(L, data.bytes, (uint)data.bytes.Length, lua_file); rc = LuaDll.lua_pcall(L, 0, 0, 0) LuaDll.lua_getglobal(L, "main"); // 传递参数 LuaDll.lua_pushinteger(L, 3333); LuaDll.lua_pushnumber(L, 3.3); // 执行main方法 int i = LuaDll.lua_pcall(L, 2, 0, 0);
3. 将C#函数提供给Lua使用,需要使用静态方法参考上面LuaFunction的定义。
LuaDll.lua_pushcfunction(L, LuaPrint); LuaDll.lua_setglobal(L, "print"); [MonoPInvokeCallback] // 这个主要是在Android上需要。 static int LuaPrint(IntPtr L) { Debug.Log("....."); return 0; }
4. Lua代码调用C#方法并提供回调,由C#函数调用。
static int FindAndBind(IntPtr L) { GameObject go = LuaDll.lua_touserdata<GameObject>(L, 1); string path = LuaDll.lua_tostring(L, 2); // 这里将lua的函数放到LUA_REGISTRYINDEX上 int idx = LuaDll.luaL_refEx(L); Transform t = go.transform.Find(path); Button btn = t.GetComponent<Button>(); btn.onClick.AddListener(delegate() { // 从LUA_REGISTRYINDEX栈获取lua的函数进行执行。 LuaDll.lua_rawgeti(L, LuaDll.LUA_REGISTRYINDEX, idx); LuaDll.lua_pcall(L, 0, 0, 0); }); return 0; }
四、总结
总体来说交互调用还是比较的简单方便,跟使用C/C++与Lua交互差不多。我仅仅简单使用Lua源码进行编译动态库使用,可以方便的替换各个版本的lua进行使用。C#导出方法给Lua使用也相对简单,但是Unity中使用Lua的时候,不可能每个类例如GameObject、Transform等都手动写导出的代码给Lua使用。这块就可以去看tolua、xlua的实现,需要考虑很多东西。