Lua学习之1 :C++调用Lua函数

一. 分享内容

      主要分享了在C++中如何调用Lua函数,包括传递参数、获取返回值。


二. 开始分享

      0. 准备Lua库

      Lua官网下载源码,这里下载的版本是5.1.5。源码根目录下的etc

件夹中有luavs.bat,这个批处理脚本可以用来在VS编译器中编译出Lua库。使用

方法是:

      依次打开VS(这里是VS2012)的TOOLS-->Visual Studio Command Prompt,

CD定位到Lua源码的根目录,如x:\xxx\lua-5.1.5,输入etc\luavs.bat,按enter。在

Lua的源码根目录的src文件夹下便多出了lua51.dll,lua51.lib库。将lua51.dll拷贝到

项目的exe目录下,并将lua51.lib、lua.h、lualib.h、lauxlib.h、luaconf.h拷贝到项目

的相应目录下(这是将lua51.lib放在cpp目录下的lib文件夹中,将lua.h、lualib.h、

lauxlib.h、luaconf.h放在放在cpp目录下的include文件夹中)。

      到此,准备Lua库的工作就结束了。

      Lua库后,在C++代码中调用Lua函数可通过以下几个步骤实现。


      1. 创建Lua运行环境

      我们知道,Lua通过lua_State的结构来保存数据,例如函数、变量等。所以

要想C++可以调用Lua函数,首先需要创建Lua运行环境。可以使用Lua提供的API

lua_open()或者luaL_newstate()来创建Lua环境。


      2. 运行Lua脚本

      在调用Lua的函数前,需要把Lua函数加载到Lua Stack中,这可以通过Lua API

luaL_dofile()来加载Lua脚本。它的返回值是0表明加载成功,而返回1表示加载失败。


      3. 初始化Lua的基本接口

      在C++中使用Lua的API之前,除了引用基本的头文件lua.h、lualib.h、lauxlib.h

以及基本的库luax.x.lib(如lua51.lib)之外,还需要做相应的库的初始化工作。例如

使用luaopen_base()初始化基本的lua库。


      4. 获取Lua函数

      加载完Lua脚本后并做相应的库的初始化工作后,想要调用Lua函数就必须先

找到它,lua_getglobal()这个LuaAPI可用来获取我们想要调用的Lua脚本中的函数。


      5. 传递参数给lua函数

      在C++代码里传递参数给Lua函数主要使用类似lua_toxxx()的这样Lua API来

现,例如传递string参数可以使用lua_pushstring(),传递int参数用lua_pushinteger()


      6. 调用Lua函数

      以上工作完成之后我们就可以调用Lua函数了,调用Lua函就是即调用Lua API中

的lua_pcall()。这个API中的参数2和参数3分别指出调用的Lua函数的参数的个数和

返回值的个数。


      7. 获取Lua函数的返回值

      通过lua_pcall()调用完Lua函数,它的返回值保存在Lua stack的顶部,所以想

获取Lua函数返回值得先知道Lua stack顶部的索引。Lua stack有两种索引方式:

负数索引和整数索引。那么Lua stack的顶部的索引也就对应有两种方式:-1和

Lua stack的大小。Lua stack的大小可由lua_gettop()获取。知道Lua stack的顶部

索引后,就可以通过形如lua_toxxx()(如使用lua_tointeger()获取int型返回值;可用

lua_tostring()获取string型返回值)的Lua API获取Lua函数的返回值了。在下面

示例代码中给出了这两中方法的使用。


      8. 编辑Lua脚本

      在Lua文件xx.lua中编写Lua函数。下面的示例是在一个myLua.lua的脚本中编写

了以下函数 

       function add(x, y)
	      return x + y
       end 


三. 示例代码

#include "stdafx.h"
#include <stdlib.h>

// include the lua header
extern "C"
{
	#include "include/lua.h"
	#include "include/lualib.h"
	#include "include/lauxlib.h"
};

// include the lua lib
#pragma comment(lib, "lib/lua51.lib")

int _tmain(int argc, _TCHAR* argv[])
{
	// 1. open lua state
	lua_State* L = lua_open(); // or call luaL_newstate()
	
	// 2. open lua base function
	luaopen_base(L);
	
	// 3. load and run lua script
	int err = luaL_dofile(L, "myLua.lua");	
	if(err)
	{
		printf("luaL_dofile() error code : %d\n", err);
		system("pause");
	}
	
	// 4. get my lua function
	lua_getglobal(L, "add");
	
	// 5. push arg to lua stack for call my lua function
	int x = 100, y = 200;	
	lua_pushinteger(L, x);
	lua_pushinteger(L, y);
	
	// 6. call my lua function
	lua_pcall(L, 2, 1, 0);

	// 7. get the return value of my lua function
	int ret = lua_tointeger(L, -1); // one top index of lua stack is -1
	printf("result of lua func add(%d, %d) : %d\n", x, y, ret);

	 second way to get the return value of my lua function
	//int n = lua_gettop(L);
	//int ret = lua_tointeger(L, n); // another top index of lua stack is the len of lua stack
	//printf("result of lua func add(%d, %d) : %d\n", x, y, ret);

	system("pause");
	return 0;
}


三. 完整的工程

      下载完整的工程



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值