加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

lua和C++相互交换数据

发布时间:2020-12-14 22:26:10 所属栏目:大数据 来源:网络整理
导读:下面的代码演示了在C++和lua脚本之间传递数据。 首先在C++中创建一个table,添加元素,然后放置到lua的全局表中。在lua脚本中可以使用C++创建的这个表。 然后在脚本中创建一个表,以脚本返回值的方式返回给C++,在C++中可以读取表中的值。 ? 例子代码需要一

下面的代码演示了在C++和lua脚本之间传递数据。

首先在C++中创建一个table,添加元素,然后放置到lua的全局表中。在lua脚本中可以使用C++创建的这个表。

然后在脚本中创建一个表,以脚本返回值的方式返回给C++,在C++中可以读取表中的值。

?

例子代码需要一个args.lua的lua文件,要手工创建,我把它放到了C盘根目录下。

// cpplua.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

extern "C"
{
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include <iostream>

/* args.lua文件的内容
io.write( "[lua] These args were passed into the script from C/n" );

for i=1,table.getn(arg) do
print(i,arg[i])
end

io.write("[lua] Script returning data back to C/n")

local temp = {}
temp[1]=9
temp[2]=8
temp[3]=7
temp[4]=6
temp[5]=5
temp["test1 key"]="test1 value"
temp[6]="test 6"
temp["test 99"]=99

for i,n in pairs(temp)
do 
print (i,n)
end

return temp,9,1

*/
int _tmain(int argc,_TCHAR* argv[])
{
	int status;

	// lua_open: 创建一个新的lua环境
	lua_State* state = lua_open();

	// 在state环境上打开标准库,
	// 标准库包括:
	// luaopen_base
	// luaopen_package
	// luaopen_table
	// luaopen_io
	// luaopen_os
	// luaopen_string
	// luaopen_math
	// luaopen_debug
	luaL_openlibs(state);  /* open libraries */

	status = luaL_loadfile( state,"c://args.lua" );

	std::cout << "[C++] Passing 'arg' array to script" << std::endl;

	// 创建一个新的表
	lua_newtable( state );

	//
	// set first element "1" to value 45
	//
	// 调用lua的函数,都是通过压栈出栈来完成的
	// 为表执行一个t[k]=v的操作,则需要先将k压栈,再将v压栈,再调用操作函数
	// lua_rawset直接赋值(不触发metamethods方法)。 
	
	// lua_rawset/lua_settable使用:
	// 它从栈中获取参数。以table在栈中的索引作为参数,
	// 并将栈中的key和value出栈。
	// lua_pushnumber函数调用之前,
	// table是在栈顶位置(索引为-1)。index和value入栈之后,
	// table索引变为-3。
	lua_pushnumber( state,1 );
	lua_pushnumber( state,45 );
	lua_rawset( state,-3 );

	// set second element "2" to value 99
	lua_pushnumber( state,2 );
	lua_pushnumber( state,99 );
	lua_rawset( state,-3 );

	// set the number of elements (index to the last array element)
	// lua_pushliteral压入一个字符串,不需要指定长度
	// 如果lua_pushlstring,则需要指定长度
	lua_pushliteral( state,"n" );
	lua_pushnumber( state,2 );
	lua_rawset( state,-3 );

	// set the name of the array that the script will access
	// Pops a value from the stack and sets it as the new value of global name.
	// 从栈顶弹出一个值,并将其设置全局变量"arg"的新值。
	lua_setglobal( state,"arg" );


	std::cout << "[C++] Running script" << std::endl;

	int result = 0;
	if (status == 0)
	{
		result = lua_pcall( state,LUA_MULTRET,0 );
	}
	else
	{
		std::cout << "bad" << std::endl;
	}

	if (result != 0)
	{
		std::cerr << "[C++] script failed" << std::endl;
	}

	std::cout << "[C++] These values were returned from the script" << std::endl;

	// lua_gettop返回栈顶的索引
	// 如果索引为0,则表示栈为空
	while (lua_gettop( state ))
	{
		switch (lua_type( state,lua_gettop( state ) ))
		{
		case LUA_TNUMBER:
			{
				std::cout << "script returned " << lua_tonumber( state,lua_gettop( state ) ) << std::endl; 
				break;
			}
		case LUA_TTABLE:  
			{
				std::cout << "script returned a table" << std::endl; 
				
				// 简单的遍历表的功能
				// ***好像lua不保存表的元素的添加顺序***

				// 压入第一个键
				lua_pushnil(state);  /* 第一个 key */
				int t = -2;
				while (lua_next(state,t) != 0)
				{
					/* 'key' (索引-2) 和 'value' (索引-1) */
					const char* key = "unknown";
					const char* value;
					if(lua_type(state,-2) == LUA_TSTRING)
					{
						key = lua_tostring(state,-2);
						value = lua_tostring(state,-1);
					}
					else if(lua_type(state,-2) == LUA_TNUMBER)
					{
						// 因为lua_tostring会更改栈上的元素,
						// 所以不能直接在key上进行lua_tostring
						// 因此,复制一个key,压入栈顶,进行lua_tostring
						lua_pushvalue(state,-2);
						key = lua_tostring(state,-1);
						lua_pop(state,1);
						value = lua_tostring(state,-1);
					}
					else
					{
						value = lua_tostring(state,-1);
					}

					std::cout   <<"key="<< key 
								<< ",value=" << value << std::endl;

					/* 移除 'value' ;保留 'key' 做下一次迭代 */
					lua_pop(state,1);
				}

				break;
			}
		case LUA_TSTRING: 
			{
				std::cout << "script returned " << lua_tostring( state,lua_gettop( state ) ) << std::endl;
				break;
			}
		case LUA_TBOOLEAN:
			{
				std::cout << "script returned " << lua_toboolean( state,lua_gettop( state ) ) << std::endl;
				break;
			}
		default: 
			std::cout << "script returned unknown param" << std::endl; 
			break;
		}
		lua_pop( state,1 );
	}
	lua_close( state );
	return 0;
}

本例用了一个控制台工程,输出如下:

[C++] Passing 'arg' array to script [C++] Running script [lua] These args were passed into the script from C 1?????? 45 2?????? 99 [lua] Script returning data back to C 1?????? 9 2?????? 8 3?????? 7 4?????? 6 5?????? 5 6?????? test 6 test 99 99 test1 key?????? test1 value [C++] These values were returned from the script script returned 1 script returned 9 script returned a table key=1,value=9 key=2,value=8 key=3,value=7 key=4,value=6 key=5,value=5 key=6,value=test 6 key=test 99,value=99 key=test1 key,value=test1 value

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读