前面有讲到一些LUA的基本知识,现在就来了解LUA是怎么样调用C++的函数的
首先,定义函数,要被LUA所调用的C++函数都有统一的格式:
typedef int (*lua_CFunction) (lua_State *L);这个C函数接受单一的参数Lua state,返回一个表示返回值个数的数字。所以,函数在将返回值入栈之前不需要清理栈,函数返回之后,Lua自动的清除栈中返回结果下面的所有内容。
如:
static int l_sin (lua_State *L ) {double d = lua_tonumber(L, 1); /* get argument */lua_pushnumber(L, sin(d)); /* push result */return 1; /* number of results */}其次,就是要注册函数:
void lua_register (lua_State *L, const char *name, lua_CFunction f);
把 C 函数 f 设到全局变量name中。它通过一个宏定义:
#define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n))
其中,char *name是是脚本中要调用c++函数的函数名,lua_CFunction fc++中函数名.
如:
lua_register(L,"MySin",l_sin);
然后在脚本中:
a=MySin(3.1415926/4)
下面是一个完整的程序:
// 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
#include
#include
using namespace std;
#pragma comment( lib ,"D:\\My Documents\\Visual Studio 2005\\Projects\\lua\\release\\lua.lib")
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;
}在用C语言调用LUA脚本引擎时,必须对脚本的错误进行识别和处理
1.错误类型
LUA错误共有以下5种,分别对应的是5个宏定义:
- #define LUA_YIELD 1 //线程被挂起
- #define LUA_ERRRUN 2 //运行时错误
- #define LUA_ERRSYNTAX 3 //编译错误
- #define LUA_ERRMEM 4 //内存分配错误
- #define LUA_ERRERR 5 //在运行错误处理函数时发生的错误
//加载脚本---------------------------------------------------------------------------
void Loadfile(const char *fileName)
{
int erro=luaL_loadfile(L, fileName);
if (erro|| lua_pcall(L, 0, 0, 0)!=0)
{
char msg[256];
sprintf(msg,"加载LUA文件错误%d%s",erro,lua_tostring(L, -1));
::MessageBox(0,msg,0,0);
}
}// 调用Lua函数--------------------------------------------------------------------
int erro= lua_pcall(L,1,0,0);
if(erro!=0)
{
char msg[256];
sprintf(msg,"调用函数错误%d%s",erro,lua_tostring(L, -1));
::MessageBox(0,msg,0,0);
}