C# 端程式碼如下 :
using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;
public class luaTest : MonoBehaviour
{
[DllImport("lua521")]
public static extern IntPtr luaL_newstate();
[DllImport("lua521")]
public static extern void luaL_openlibs(IntPtr lua_State);
[DllImport("lua521")]
public static extern void lua_close(IntPtr lua_State);
[DllImport("lua521")]
public static extern void lua_pushcclosure(IntPtr lua_State, LuaFunction func, int n);
[DllImport("lua521")]
public static extern void lua_setglobal(IntPtr lua_State, string s);
[DllImport("lua521")]
public static extern int lua_pcallk(IntPtr lua_State, int nargs, int nresults, int errfunc, int ctx, LuaFunction func);
[DllImport("lua521")]
public static extern int luaL_loadfilex(IntPtr lua_State, string s, string mode);
[DllImport("lua521")]
public static extern int luaL_loadstring(IntPtr lua_State, string s);
[DllImport("lua521")]
public static extern IntPtr luaL_checklstring(IntPtr lua_State, int idx, IntPtr len);
[DllImport("lua521")]
public static extern int lua_rawgeti(IntPtr lua_State, int idx0, int idx1);
[DllImport("lua521")]
public static extern int luaL_ref(IntPtr lua_State, int idx);
[DllImport("lua521")]
public static extern int luaL_unref(IntPtr lua_State, int idx0, int idx1);
[DllImport("lua521")]
public static extern int lua_pushnumber(IntPtr lua_State, double num);
//------------------------------------
// Lua
//
//註冊 C# Function 讓 Lua 可以呼叫執行
public delegate int LuaFunction(IntPtr pLuaState);
public static void lua_register(IntPtr pLuaState, string strFuncName, LuaFunction pFunc)
{
lua_pushcclosure(pLuaState, pFunc, 0);
lua_setglobal(pLuaState, strFuncName);
}
//執行 Lua 檔案
public static int luaL_dofile(IntPtr lua_State, string s)
{
if (luaL_loadfilex(lua_State, s, null) != 0)
return 1;
return lua_pcallk(lua_State, 0, -1, 0, 0, null);
}
//執行 Lua Callback Function
public static int luaL_doCallBackFromCBIdx(IntPtr lua_State, int idx, double num)
{
lua_rawgeti(lua_State, -1000000 - 1000, idx);
lua_pushnumber(lua_State, num);
int ret = lua_pcallk(lua_State, 1, 0, 0, 0, null);
if (ret != 0)
{
//Error...
}
luaL_unref(lua_State, -1000000 - 1000, idx);
return ret;
}
//------------------------------------
// Application
//
public static int nLuaCBFuncIdx = -1;
public static IntPtr m_luaState = IntPtr.Zero;
public static int tellMeNum(IntPtr pLuaState)
{
//取得回呼函數堆疊上的 index
nLuaCBFuncIdx = luaL_ref(pLuaState, -1000000 - 1000);
return 0;
}
//讓 Lua 在 unity 裡顯示 log 訊息
public static int msg(IntPtr pLuaState)
{
IntPtr retPtr = luaL_checklstring(pLuaState, 1, IntPtr.Zero);
string retStr = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(retPtr);
Debug.Log(retStr);
return 0;
}
//取得 unity 執行路徑
public static string GetAppPath()
{
return Application.dataPath.Substring(0, Application.dataPath.Length - 6);
}
// Use this for initialization
void Start()
{
//初始化 Lua
m_luaState = luaL_newstate();
luaL_openlibs(m_luaState);
//註冊 C# Function
lua_register(m_luaState, "tellMeNum", tellMeNum);
lua_register(m_luaState, "msg", msg);
//執行 Lua 檔案
string strPath = GetAppPath() + "LuaScript/lua.txt";
luaL_dofile(m_luaState, strPath);
}
// Update is called once per frame
void Update()
{
if (nLuaCBFuncIdx != -1)
{
//回呼取得的 lua callback function, 並給予數字 12345.678
luaL_doCallBackFromCBIdx(m_luaState, nLuaCBFuncIdx, 12345.678);
nLuaCBFuncIdx = -1;
}
}
void OnApplicationQuit()
{
lua_close(m_luaState);
}
}
其中值得注意的是 luaL_doCallBackFromCBIdx 函數,其用來回呼 Lua Callback Function。lua.txt 內容如下:
function dispResult(num) msg(num) end tellMeNum(dispResult)此 lua script 呼叫 tellMeNum 並將 dispResult 以參數傳給 C#,待 C# 呼叫 dispResult,dispResult 接收到 num 之後呼叫 msg 使 num 顯示在 Unity Console。
完整範例程式可在此取得:https://github.com/phardera/unity3d_lua_callback_function.git
0 意見 :
張貼留言