天天看点

在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。