Chinaunix首页 | 论坛 | 博客
  • 博客访问: 231988
  • 博文数量: 56
  • 博客积分: 2480
  • 博客等级: 大尉
  • 技术积分: 475
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-28 10:57
文章分类

全部博文(56)

文章存档

2012年(36)

2011年(4)

2010年(2)

2009年(14)

我的朋友

分类: Python/Ruby

2012-03-07 17:52:30

 lua和C++相互交换数据
 1273人阅读 评论(1) 收藏 举报

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

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

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

 

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

  1. // cpplua.cpp : Defines the entry point for the console application.  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5.   
  6. extern "C"  
  7. {  
  8. #include   
  9. #include   
  10. #include   
  11. }  
  12. #include   
  13.   
  14. /* args.lua文件的内容 
  15. io.write( "[lua] These args were passed into the script from C/n" ); 
  16.  
  17. for i=1,table.getn(arg) do 
  18. print(i,arg[i]) 
  19. end 
  20.  
  21. io.write("[lua] Script returning data back to C/n") 
  22.  
  23. local temp = {} 
  24. temp[1]=9 
  25. temp[2]=8 
  26. temp[3]=7 
  27. temp[4]=6 
  28. temp[5]=5 
  29. temp["test1 key"]="test1 value" 
  30. temp[6]="test 6" 
  31. temp["test 99"]=99 
  32.  
  33. for i,n in pairs(temp) 
  34. do  
  35. print (i,n) 
  36. end 
  37.  
  38. return temp,9,1 
  39.  
  40. */  
  41. int _tmain(int argc, _TCHAR* argv[])  
  42. {  
  43.     int status;  
  44.   
  45.     // lua_open: 创建一个新的lua环境  
  46.     lua_State* state = lua_open();  
  47.   
  48.     // 在state环境上打开标准库,  
  49.     // 标准库包括:  
  50.     // luaopen_base  
  51.     // luaopen_package  
  52.     // luaopen_table  
  53.     // luaopen_io  
  54.     // luaopen_os  
  55.     // luaopen_string  
  56.     // luaopen_math  
  57.     // luaopen_debug  
  58.     luaL_openlibs(state);  /* open libraries */  
  59.   
  60.     status = luaL_loadfile( state, "c://args.lua" );  
  61.   
  62.     std::cout << "[C++] Passing 'arg' array to script" << std::endl;  
  63.   
  64.     // 创建一个新的表  
  65.     lua_newtable( state );  
  66.   
  67.     //  
  68.     // set first element "1" to value 45  
  69.     //  
  70.     // 调用lua的函数,都是通过压栈出栈来完成的  
  71.     // 为表执行一个t[k]=v的操作,则需要先将k压栈,再将v压栈,再调用操作函数  
  72.     // 这个操作函数会使用栈上的元素,并“可能”将弹出元素和压入元素  
  73.     // lua_rawset直接赋值(不触发metamethods方法)。   
  74.       
  75.     // lua_rawset/lua_settable使用:  
  76.     // 它从栈中获取参数。以table在栈中的索引作为参数,  
  77.     // 并将栈中的key和value出栈。  
  78.     // lua_pushnumber函数调用之前,  
  79.     // table是在栈顶位置(索引为-1)。index和value入栈之后,  
  80.     // table索引变为-3。  
  81.     lua_pushnumber( state, 1 );  
  82.     lua_pushnumber( state, 45 );  
  83.     lua_rawset( state, -3 );  
  84.   
  85.     // set second element "2" to value 99  
  86.     lua_pushnumber( state, 2 );  
  87.     lua_pushnumber( state, 99 );  
  88.     lua_rawset( state, -3 );  
  89.   
  90.     // set the number of elements (index to the last array element)  
  91.     // lua_pushliteral压入一个字符串,不需要指定长度  
  92.     // 如果lua_pushlstring,则需要指定长度  
  93.     lua_pushliteral( state, "n" );  
  94.     lua_pushnumber( state, 2 );  
  95.     lua_rawset( state, -3 );  
  96.   
  97.     // set the name of the array that the script will access  
  98.     // Pops a value from the stack and sets it as the new value of global name.  
  99.     // 从栈顶弹出一个值,并将其设置全局变量"arg"的新值。  
  100.     lua_setglobal( state, "arg" );  
  101.   
  102.   
  103.     std::cout << "[C++] Running script" << std::endl;  
  104.   
  105.     int result = 0;  
  106.     if (status == 0)  
  107.     {  
  108.         result = lua_pcall( state, 0, LUA_MULTRET, 0 );  
  109.     }  
  110.     else  
  111.     {  
  112.         std::cout << "bad" << std::endl;  
  113.     }  
  114.   
  115.     if (result != 0)  
  116.     {  
  117.         std::cerr << "[C++] script failed" << std::endl;  
  118.     }  
  119.   
  120.     std::cout << "[C++] These values were returned from the script" << std::endl;  
  121.   
  122.     // lua_gettop返回栈顶的索引  
  123.     // 如果索引为0,则表示栈为空  
  124.     while (lua_gettop( state ))  
  125.     {  
  126.         switch (lua_type( state, lua_gettop( state ) ))  
  127.         {  
  128.         case LUA_TNUMBER:  
  129.             {  
  130.                 std::cout << "script returned " << lua_tonumber( state, lua_gettop( state ) ) << std::endl;   
  131.                 break;  
  132.             }  
  133.         case LUA_TTABLE:    
  134.             {  
  135.                 std::cout << "script returned a table" << std::endl;   
  136.                   
  137.                 // 简单的遍历表的功能  
  138.                 // ***好像lua不保存表的元素的添加顺序***  
  139.   
  140.                 // 压入第一个键  
  141.                 lua_pushnil(state);  /* 第一个 key */  
  142.                 int t = -2;  
  143.                 while (lua_next(state, t) != 0)  
  144.                 {  
  145.                     /* 'key' (索引-2) 和 'value' (索引-1) */  
  146.                     const char* key = "unknown";  
  147.                     const char* value;  
  148.                     if(lua_type(state, -2) == LUA_TSTRING)  
  149.                     {  
  150.                         key = lua_tostring(state, -2);  
  151.                         value = lua_tostring(state, -1);  
  152.                     }  
  153.                     else if(lua_type(state, -2) == LUA_TNUMBER)  
  154.                     {  
  155.                         // 因为lua_tostring会更改栈上的元素,  
  156.                         // 所以不能直接在key上进行lua_tostring  
  157.                         // 因此,复制一个key,压入栈顶,进行lua_tostring  
  158.                         lua_pushvalue(state, -2);  
  159.                         key = lua_tostring(state, -1);  
  160.                         lua_pop(state, 1);  
  161.                         value = lua_tostring(state, -1);  
  162.                     }  
  163.                     else  
  164.                     {  
  165.                         value = lua_tostring(state, -1);  
  166.                     }  
  167.   
  168.                     std::cout   <<"key="<< key   
  169.                                 << ", value=" << value << std::endl;  
  170.   
  171.                     /* 移除 'value' ;保留 'key' 做下一次迭代 */  
  172.                     lua_pop(state, 1);  
  173.                 }  
  174.   
  175.                 break;  
  176.             }  
  177.         case LUA_TSTRING:   
  178.             {  
  179.                 std::cout << "script returned " << lua_tostring( state, lua_gettop( state ) ) << std::endl;  
  180.                 break;  
  181.             }  
  182.         case LUA_TBOOLEAN:  
  183.             {  
  184.                 std::cout << "script returned " << lua_toboolean( state, lua_gettop( state ) ) << std::endl;  
  185.                 break;  
  186.             }  
  187.         default:   
  188.             std::cout << "script returned unknown param" << std::endl;   
  189.             break;  
  190.         }  
  191.         lua_pop( state, 1 );  
  192.     }  
  193.     lua_close( state );  
  194.     return 0;  
  195. }  

 

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

[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

阅读(1511) | 评论(0) | 转发(0) |
0

上一篇:Lua和C的交互说明(函数)

下一篇:lua c++ 1

给主人留下些什么吧!~~