Lua与C的相互调用

闲的蛋疼,让C和Lua玩包剪锤。结果C以微弱的优势胜出了。

言归正传,这次主要是想练习Lua和C的相互调用。

一、C调用Lua函数

1. luaL_dofile(L, fn);

该函数可以让Lua虚拟栈读取路径为fn的Lua文件,其实质是:

lua_loadfile(L, fn) || lua_pcall(L, 0, Lua_MUTIRET, 0)

实际上,lua_loadfile只是把Lua文件加载到VM,成为一个可执行的对象,但却还没有执行它,所以还不能使用。

而lua_pcall则把该Lua文件运行了。只有运行了该文件才可以使用其函数。

2. lua_getglobal(L, s)

把全局变量s压入栈顶

3. lua_pushnumber(L, arg)

把参数压入栈顶。

4. lua_pcall(L, nargs, nreturns, errorfunc)

运行栈顶函数,传入参数个数后,虚拟栈会自动pop出相应数量的参数供Lua函数使用。

二、Lua调用C函数

1. 首先要在C中注册C函数到Lua虚拟栈 : lua_register(L, n, f)

可以把名为n的函数f注册到Lua虚拟栈中。其可以分为两步:

lua_pushcfunction(L, f)

lua_setglobal(L, n)

即首先把函数f压入栈顶,再将其pop出来,并设为全局变量。

2. 在lua中调用C函数,直接调用即可

3. 该C函数可以用luaL_checknumber(L, idx)获取栈中序号为idx的参数

4. return 的整型数代表C返回给Lua的返回值个数。 可以先用lua_pushnumber把要返回的值压入栈

关于石头剪刀布的随机,由于没有去维护一个给lua的全局变量随机种子,故每次用C随机了一颗种子给lua,再让lua产生随机数。

另外,本人并没有做错误判断和处理,程序的健壮性尚佳,读者们可以自己思考下哪里需要加上错误判断和处理,加强理解。

代码清单:

1. lua_psr.lua

1 function lua_psr (c_r,seed)
2 math.randomseed(seed);
3 lua_r = math.random(3)-1;
4 c_win,c_draw,c_lose = judge(c_r, lua_r);
5 print_log("the result: c_win = "..c_win.." c_draw = "..c_draw.." c_lose = "..c_lose.."\n");
6 end

Lua_psr.lua

2.  testLua.cpp

 1 #include <stdio.h>
2 #include <string.h>
3 #include <string>
4 #include <time.h>
5 #include <stdlib.h>
6 extern "C" {
7 #include <lua.h>
8 #include <lauxlib.h>
9 #include <lualib.h>
10 }
11
12 int c_win;
13 int c_lose;
14 int c_draw;
15
16 // called in lua
17 int print_log(lua_State* L)
18 {
19 std::string str = luaL_checkstring(L, 1);
20 printf("%s", str.c_str());
21 return 0;
22 }
23
24 // called in lua
25 int judge(lua_State *L)
26 {
27 int c = luaL_checknumber(L, 1);
28 int lua = luaL_checknumber(L, 2);
29 if (0 == c - lua)
30 {
31 c_draw++;
32 }
33 else if (-1 == c - lua || 2 == c - lua)
34 {
35 c_lose++;
36 }
37 else
38 {
39 c_win++;
40 }
41 //printf("now the result is : c_win=%d c_draw=%d c_lose=%d ",c_win,c_draw,c_lose);
42 lua_pushnumber(L, c_win);
43 lua_pushnumber(L, c_draw);
44 lua_pushnumber(L, c_lose);
45 return 3;
46 }
47
48 int psr()
49 {
50 int r = rand()%3;
51 return r;
52 }
53
54 void lua_psr(lua_State* L, int r)
55 {
56 lua_getglobal(L, "lua_psr");
57 lua_pushnumber(L, r);
58 int seed = rand()%100000000;
59 lua_pushnumber(L, seed);
60 lua_pcall(L, 2, 0, 0);
61 }
62
63 int main (void)
64 {
65 srand(time(NULL));
66 freopen("paper_scissor_rock_c_vs_lua_result.txt", "w", stdout);
67 lua_State *L = luaL_newstate();
68 luaL_openlibs(L);
69 if (0 != luaL_dofile(L, "lua_psr.lua"))
70 {
71 printf("lua file not found!");
72 return 0;
73 }
74 lua_register(L, "judge", judge);
75 lua_register(L, "print_log", print_log);
76 printf("now begin! paper scissor rock c vs lua!\n");
77 for (int i = 0; i < 100; i++)
78 {
79 int r = psr();
80 lua_psr(L, r);
81 }
82 printf("total turns: %d\n", c_win + c_draw + c_lose);
83 printf("c_win: %d\n", c_win);
84 printf("c_draw: %d\n", c_draw);
85 printf("c_lose: %d\n", c_lose);
86 return 0;
87 }

testLua.cpp

时间: 2024-10-11 21:12:10

Lua与C的相互调用的相关文章

lua与c++的相互调用

一.   lua调用C++       在lua中是以函数指针的形式调用函数, 并且所有的函数指针都必须满足如下此种类型: typedef int (*lua_CFunction) (lua_State *L); 也就是说, 偶们在C++中定义函数时必须以lua_State为参数, 以int为返回值才能被Lua所调用. 但是不要忘记了, 偶们的lua_State是支持栈的, 所以通过栈可以传递无穷个参数, 大小只受内存大小限制. 而返回的int值也只是指返回值的个数真正的返回值都存储在lua_S

lua与c++的相互调用入门篇

进入游戏行业,开始学习lua,lua脚本语言的优势在于灵活,游戏行业应用相当广泛,因为支持动态加载,所以是必不可少的存在.可以想想,如果死守C++不放,有一个bug,莫非修正bug后重启服务器?这得浪费多少时间? 好了,废话少说,上流程. 1:下载lua源码:http://www.lua.org/ftp/ 2:建立控制台应用程序,选择“静态库”,去掉“预编译头”选项 3:将下载的lua源码 添加到工程,如下图 4:选择Release 模式 5:为了防止4996错误,在“预处理器”中加入 “_CR

C程序与Lua脚本相互调用

Lua脚本是一种可用于C程序开发/测试的工具,本篇介绍一下C程序与Lua脚本如何进行相互调用,更加详细的操作参见<Programing in Lua>.本文分为3个部分:1.Windows环境下Lua的下载以及安装注意事项:2.Visual C++6.0中Lua的配置:3.C程序与Lua脚本相互调用实例. 1.Windows环境下Lua的下载以及安装注意事项 a.下载Lua for Windows,笔者用的版本是V5.1.4-35: b.上微软官网,下载Visual C++运行库——vcred

lua编程之lua与C相互调用

lua是扩展性非常良好的语言,虽然核心非常精简,但是用户可以依靠lua库来实现大部分工作.除此之外,lua还可以通过与C函数相互调用来扩展程序功能.在C中嵌入lua脚本既可以让用户在不重新编译代码的情况下修改lua代码更新程序,也可以给用户提供一个自由定制的接口,这种方法遵循了机制与策略分离的原则.在lua中调用C函数可以提高程序的运行效率.lua与C的相互调用在工程中相当实用,本文就来讲解lua与C相互调用的方法. Lua与C相互调用的首要问题是如何交换数据,lua API使用了一个抽象的栈与

lua和C++相互调用

从lua调用C++函数和对象,利用LuaPlus可以方便的从C++中调用lua脚本,反过也一样.通过注册函数或类对象,lua便可以访问C++. 一.C风格函数注册    Lua提供了C风格的回调函数注册,该函数原型如下: int Callback(LuaState* state); 无论是全局函数.类非虚函数.类虚函数,只要符合上面的原型,都可以向Lua注册.我们以全局函数为例,下面是我们提供的一个回调函数CStyleAddFunc: int CStyleAddFunc(LuaState * s

Cocos2d-x3.0下 Lua与C++相互调用

这里讲下Lua与C++之间如何实现相互调用 原文连接:http://blog.csdn.net/qqmcy/article/details/26052771 DJLCData.h 实现类 // // DJLCData.h // uitestLua // // Created by 杜甲 on 14-5-17. // // #ifndef __uitestLua__DJLCData__ #define __uitestLua__DJLCData__ #include "cocos2d.h"

菜鸟入门之lua与c++相互调用(包含多个demo)

前两篇文章中,已经介绍了使用vs2010编译lua5.1源码生成lua.lib 和 vs项目中使用c++调用lua,可以保证demo在vs上运行起来了.这里再详细介绍下c++和lua之间的相互调用以及原理. c++与lua直接的调用,实际上通过一个栈结构来传递数据,该栈结构栈顶的索引值为-1,向栈底方向索引值依次为-1 ,-2......栈顶索引为1.栈结构里可以放函数,表,字符串,整形等各种lua的基本数据. 一.在当前cpp目录下创建test.lua文件,用于与c++交互调用,代码如下: p

Lua与C++相互调用

{--1.环境--} 为了快速入手,使用了小巧快速的vc++6.0编译器 以及在官网下载了Lua安装包..官网地址{--http://10.21.210.18/seeyon/index.jsp--} 两者都安装好后,即可进行 {--2.工程以及配置--} 1.首先用vc++6.0创建一个简单的win32 console application 2.从Lua的安装目录下复制include和lib两个目录下的文件到刚刚创建的工程的目录下. {include:包含了lua的.h头文件} {lib:包含

uLua学习笔记(三):Unity3D和Lua之间的相互调用

这篇笔记主要集中学习一下uLua和Unity3D之间相互调用的方法,我们导入了uLua之后,现在会弹出一个类似学习屏幕的东西,如下: 先赞一个! Unity3D调用Lua Unity3D调用Lua的方法还是比较简单的,所以先说这个,由于这部分在学习笔记(一)中已经说的挺多的了,更多的内容点击这里回去看,所以这里我们就来看一个简单的示例即可: 1 using LuaInterface; 2 using UnityEngine; 3 4 public class UnityCallLua : Mon