Calling Lua function from C#

The simplest way to call a lua global function from C#:
最樸素的從 C# 調用 lua 的一個全局函數的寫法:

// 相當於 lua 裏一個這樣的調用 foo("test", 42)
// equal to lua code: foo("test", 42)

Lua.GetGlobal( "foo" ); // 加載 lua 中定義的一個名叫 foo 的全局函數到堆棧
Debug.Assert( Lua.IsFunction(-1) ); // 確保加載成功了, 此時棧頂是函數 foo
Lua.PushString( "test" ); // 將第一個參數(字符串 "test")入棧
Lua.PushInteger( 42 ); //將第二個參數(整數 42)入棧
Lua.Call(2, 0); // 調用函數 foo, 指明有2個參數,沒有返回值

More complicated examples can be found in:
稍微複雜一點的例子可以參考實例程序裏的一些簡單寫法。參考:

// 創建 Lua 虛擬機
// create Lua VM instance
var Lua = LuaAPI.NewState();

// 加載基本庫
// load base libraries
Lua.L_OpenLibs();

// 加載並運行 Lua 腳本文件
// load and run Lua script file
var LuaScriptFile = "framework/main.lua";
var status = Lua.L_DoFile( LuaScriptFile );

// 捕獲錯誤
// capture errors
if( status != ThreadStatus.LUA_OK )
{
    throw new Exception( Lua.ToString(-1) );
}

// 確保 framework/main.lua 執行結果是一個 Lua table
// ensuare the value returned by 'framework/main.lua' is a Lua table
if( ! Lua.IsTable(-1) )
{
  throw new Exception(
		"framework main's return value is not a table" );
}

// 從 framework/main.lua 返回的 table 中讀取 awake 字段指向的函數
// 並保存到 AwakeRef 中 (可以將 AwakeRef 視爲這個函數的句柄)
var AwakeRef = StoreMethod( "awake" );

// 不再需要 framework/main.lua 返回的 table 了,將其從棧上彈出
Lua.Pop(1);

//----------------------------------------------------

// 在需要的時候可以這樣調用 AwakeRef 指向的 lua 函數
CallMethod( AwakeRef );

//----------------------------------------------------
// StoreMethod 和 CallMethod 的實現

private int StoreMethod( string name )
{
	Lua.GetField( -1, name );
	if( !Lua.IsFunction( -1 ) )
	{
		throw new Exception( string.Format(
			"method {0} not found!", name ) );
	}
	return Lua.L_Ref( LuaDef.LUA_REGISTRYINDEX );
}

private void CallMethod( int funcRef )
{
	Lua.RawGetI( LuaDef.LUA_REGISTRYINDEX, funcRef );
	var status = Lua.PCall( 0, 0, 0 );
	if( status != ThreadStatus.LUA_OK )
	{
		Debug.LogError( Lua.ToString(-1) );
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章