本質(zhì)上是定義一個(gè)lua_CFunction,然后通過(guò)把關(guān)聯(lián)到Lua中的一個(gè)table中,默認的比如lua_register,實(shí)際上是把這個(gè)函數關(guān)聯(lián)到global表的對應key上,其他的也可以關(guān)聯(lián)到自己定義的table上,比如:
lua_pushstring(l,"export_table");lua_rawget(l,LUA_REGISTRYINDEX);if (lua_istable(l,-1)){ lua_pushstring(l,"function_name"); lua_pushcfunction(l,lua_CFunction_define); // 相當于export_table[function_name] = lua_CFunction_define; lua_rawset(l,-3);}lua_pop(l, 1);通過(guò)lua_call和lua_pcall實(shí)現,先把函數壓棧,這里的函數是在lua中的function,由于上面C函數可以關(guān)聯(lián)到lua的某個(gè)table中,所以,理論上也可以是C函數,然后把返回結果再壓棧。具體參數含義見(jiàn)API說(shuō)明。
The following example shows how the host program can do the equivalent to this Lua code:
a = f("how", t.x, 14)Here it is in C:
lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* function to be called */ lua_pushstring(L, "how"); /* 1st argument */ lua_getfield(L, LUA_GLOBALSINDEX, "t"); /* table to be indexed */ lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */ lua_remove(L, -2); /* remove 't' from the stack */ lua_pushinteger(L, 14); /* 3rd argument */ lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */ lua_setfield(L, LUA_GLOBALSINDEX, "a"); /* set global 'a' */Note that the code above is "balanced": at its end, the stack is back to its original configuration. This is considered good programming practice.
以上引用自官方
Manual
C#調用C的代碼是通過(guò)P/invoke, 即平臺調用,.net 提供了一種托管代碼調用非托管代碼的機制。
通過(guò)DllImport特性實(shí)現,把c的相關(guān)函數聲明成 static, extern的形式,還可以為方法的參數和返回值指定自定義封送處理信息。
具體可以參考msdn的描述
C代碼調用C#是通過(guò)delegate實(shí)現的,即把需要被調用的C#函數都聲明成delegate,然后通過(guò)把函數地址通過(guò)DllImport已經(jīng)導出的函數傳入非托管代碼(C代碼),其中Marshal.GetFunctionPointerForDelegate可以獲取函數指針。
有了上面的過(guò)程,下面的就好說(shuō)了
C# --》C --》Lua
Lua --》C --》C#, 以下部分代碼摘自Slua
public delegate int LuaCSFunction(IntPtr luaState);[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]public static extern void lua_pushcclosure(IntPtr l, IntPtr f, int nup);public static void lua_pushcclosure(IntPtr l, LuaCSFunction f, int nup){ IntPtr fn = Marshal.GetFunctionPointerForDelegate(f); lua_pushcclosure(l, fn, nup);}LuaDLL.lua_pushcfunction(L, print);LuaDLL.lua_setglobal(L, "print");print定義如下
static int print(IntPtr L)以上就是C,C#,Lua互相調用的一個(gè)簡(jiǎn)單理解。
聯(lián)系客服