天天看點

在Lua中使用自己的C函數

-------以下是Lua腳本--------

--test.lua

LuaC_MessageBox( "Last is ShowMessage! This is real MessageBox!");

---------通過LuaEdit文法測試才出鬼了--------------

//------------以下是test.cpp檔案----------------

//================================================================================================================

//Lua Test Object

//C++ Source lua_test.cpp

//================================================================================================================

//================================================================================================================

//Include Files

//================================================================================================================

extern "C"

{

#include "D:\\My Documents\\Visual Studio 2005\\Projects\\lua\\lua\\lua.h"

#include "D:\\My Documents\\Visual Studio 2005\\Projects\\lua\\lua\\lualib.h"

#include "D:\\My Documents\\Visual Studio 2005\\Projects\\lua\\lua\\lauxlib.h"

}

#include <windows.h>

#include <stdio.h>

#include <string>

using namespace std;

//================================================================================================================

//Libraries

//================================================================================================================

#pragmacomment( lib ,"D:\\My Documents\\Visual Studio 2005\\Projects\\lua\\release\\lua.lib")

//================================================================================================================

//Global Variables

//================================================================================================================

lua_State *L;

//================================================================================================================

//Lua Functions

//================================================================================================================

double f( double x, double y )

{

double ret;

lua_getglobal( L, "f");

lua_pushnumber( L,x);

lua_pushnumber( L,y);

lua_call( L, 2, 1);

//lua_pcall( L, 2, 1, 0);

ret = lua_tonumber( L, -1);

//lua_pop( L, 1);

return ret;

}

//================================================================================================================

//C/C++ Functions

//================================================================================================================

int LuaC_MessageBox( lua_State *L)

{

char Message[256] = "";

int i;

// 擷取參數個數

int n = lua_gettop(L);

// 儲存全部參數

for ( i = 1, j = 0; i <= n ; i++)

{

if( lua_isstring( L, i))

strcpy( Message, lua_tostring( L, i));

}

// 執行邏輯

MessageBox( NULL, Message,"Lua Test", MB_OK);

// 傳回值壓棧

// 傳回壓棧參數的個數

return 0;

}

//================================================================================================================

//Main Functions

//================================================================================================================

int main( void)

{

int error;

L = lua_open();

luaopen_base(L);

luaL_openlibs(L);

// 注冊C/C++函數

lua_register( L, "LuaC_MessageBox", LuaC_MessageBox);

// load the script

// 加入了錯誤處理

if ( (error = luaL_dofile(L, "test.lua")) != 0)

{

MessageBox( NULL, "出錯啦:執行腳本出錯!","Lua Test", MB_OK);

return 0;

}

getchar();

lua_close( L);

return 1;

}

額....這就是系列文章的好處:即使CSDN把原來的弄丢了,我也可以根據上下文來重寫丢失的文章。

如你所見,我将關鍵點全部标記為粗體。并且給出了足夠的注釋。讓我們來一條條梳理:

1、LuaC_MessageBox( "Last is ShowMessage! This is real MessageBox!");

這就是Lua腳本調用自己寫的函數。讓我們接着看如何實作這個函數的。

2、int LuaC_MessageBox( lua_State *L)

這個就是函數的實體了,要想使自己的函數被Lua腳本所用,必須遵守以下規則:

使用 int 函數名( lua_State *L) 的形式來聲明和定義函數。

使用Lua的堆棧來進行參數交換。

調用Lua的注冊函數。

3、關于第2個規則,Lua是按照 __fastcall 的規則傳遞參數的,也就是從左到右一個個傳。

Lua壓棧的順序是:首先将函數壓棧,然後将參數壓棧。執行完畢後,将參數和函數都出棧,然後将傳回值按順序壓棧。當然,還有很多類似的參數交換規則,不過别急我們慢慢來。

4、retrun 0;

在C函數中的傳回值 指的是傳回值的數量。因為Lua腳本是支援多個傳回值的,結合上條和這條規則來實作。

5、C檔案中的函數體編寫完了,還需要将該函數進行注冊,如:

lua_register( L, "LuaC_MessageBox", LuaC_MessageBox);

第二個參數為Lua腳本中的函數名,第三個為C檔案中的函數名。

6、還有什麼是我沒涉及到的?傳回值壓棧!但是我想暫時不談這個問題,因為我将(已經)在筆記四中詳細讨論。是以,先熟悉這個基本流程。

7、OK。重寫的好處在于:我可以直接把筆記四的東西搬過來。哈哈,又一次時間旅行。

Lua中有很多把各類傳回值壓棧的函數,隻要你在Lua參考手冊中搜尋“lua_push”,你可以得到如下結果:

lua_pushboolean

lua_pushinteger

lua_pushfstring

lua_pushlstring

lua_pushnil

lua_pushnumber

.....

有很多這樣的函數,解釋可以參看參考手冊(一定要看!)。

但是在這個例子中,我們沒有傳回值,是以retrun 0。