`
javababy1
  • 浏览: 1224802 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Lua学习笔记三--表的应用

阅读更多

Lua学习笔记三


2008.7.14

修正了 main 函数里 注册新Lua函数时候的一个笔误,感谢 mayao11指出以上错误:)

2008.5.20

修正了 小结 里关于 lua_pop(L,-1)的错误,应该为lua_pop(L,1),感谢 aslucky 指出以上错误。


首先提一下:元旦只放一天假,比较悲惨。不过可以继续研究Lua,也不失为一种幸运。

通过上一节的知识,我们可以实现很多应用了,但是在GUI领域,实在有太多的变量--x,y,z,w,h,bitmap,algi,d1,d2,d3,dp1,dp2,dp3,whatever...,而Lua的栈默认元素上限为20个,所以必须掌握Lua特有的数据类型--表的应用。
本节的目的:在上节的基础上,加入表的应用。侧重点为用表来作为函数参数。


请不要嫌我麻烦,这个系列文章是循序渐进式,而不是手册式,所以一定要掌握之前的知识,才可以继续阅读。
另外,请快速阅读pil的语法部分(1-7章),以便对Lua语法有大概的了解,这大概会花费1天的时间。但是不要在for循环和迭代器上花费太多的时间--如果暂时不想过于深入的理解Lua,而只是看懂这些笔记的程度--那些东西会研究的,但不是现在,现在我们只是初心者而已。
OK,这是我最后一次罗嗦这个。


RTFS?!

-------以下是Lua脚本--------
--test.lua
LuaC_MessageBoxEx{ hWnd = nil,
lpText = "Last is ShowMessage! This is real MessageBox!",
lpCaption = "Lua Test",
uType = 0} --0就是MB_OK

---------通过LuaEdit语法测试才出鬼了--------------

//------------以下是test.cpp文件----------------
//================================================================================================================
//Lua Test Object
//C++ Source lua_test.cpp
//================================================================================================================
//================================================================================================================
//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 <windows.h>
#include <stdio.h>
#include <string>
using namespace std;
//================================================================================================================
//Libraries
//================================================================================================================
#pragmacomment( lib ,"D:\\My Documents\\Visual Studio 2005\\Projects\\lua\\release\\lua.lib")
//================================================================================================================
//Global Variables
//================================================================================================================
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++ Helper Functions
//================================================================================================================

// 获取t[k](表t中字段k)的值
// 有以下的值
#define GTC_LP 0x0000 // pointer
#define GTC_INT 0x0001// int
#define GTC_DOUBLE0x0002// double
#define GTC_STRING 0x0003 // char
void _lua_getfield( lua_State* L, char* key, void* ret, int type_flags)
{
lua_pushstring( L, key);
lua_gettable( L, -2);
switch( type_flags)
{
case GTC_LP:
{
ret = (void*)lua_topointer(L,-1);
break;
}

case GTC_INT:
{
(*(int*)ret) = (int)lua_tointeger( L, -1);
break;
}
case GTC_DOUBLE:
{
(*(double*)ret) = lua_tonumber( L, -1);
break;
}
case GTC_STRING:
{
// 此处有隐患,应该阅读lua_tostring()原型之后再来处理
strcpy( (char*)ret, lua_tostring( L, -1));
break;
}
default:
break;
}
lua_pop( L, 1);
}

//================================================================================================================
//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;
}

int LuaC_MessageBoxEx( lua_State *L)
{
HWNDhWnd;
charlpText[256] = "";
charlpCaption[256] = "";
UINTuType;

//解析表
_lua_getfield( L, "hWnd", &hWnd, GTC_LP);
_lua_getfield( L, "lpText", &lpText, GTC_STRING);
_lua_getfield( L, "lpCaption", &lpCaption, GTC_STRING);
_lua_getfield( L, "uType", &uType, GTC_INT);

// 执行逻辑
MessageBox( hWnd, lpText,lpCaption, uType);

// 返回值压栈

// 返回压栈参数的个数
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);
lua_register( L, "LuaC_MessageBoxEx", LuaC_MessageBoxEx);

// 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;
}


如你所见,这2段代码是相当的熟悉,因为我直接使用上次的代码来做的修改。并且我将新添加的部分用黑体标明,以引起你的注意。所有这写新加入的代码,相应的注释里有足够的解释--除了一个帮助器函数:_lua_getfield

这一节新加的代码比较少,但是要说清楚其中的内容就不太容易了。一定要关注我用红色标记出来的部分。

1、首先注意Lua文件中的{},这是表语法。Lua语法规定,如果(LUA文件中的)函数的参数只有1个参数,并且该参数类型为一张表,就可以使用形如: 函数名{ }的形式。

2、其次是如何解析一张表。在Lua规则里,这样定义读取表元素的协议的:
Lua API 只提供了一个lua_gettable 函数, 他接受table 在栈中的位置为参数,将对应key 值出栈, 返回与key 对应的value 。我们上面的getfield 函数假定table 在栈顶, 因此,lua_pushstring 将key 入栈之后, table 在-2 的位置。返回之前, getfield 会将栈恢复到调用前的状态。(取自PIL 25.1--表操作)

这段话有点含糊不清,实际上Lua取元素的协议是:首先将一个字符串压栈,然后调用lua_gettable。
lua_gettable的实际的工作流程是:以栈顶的字符串(key)为关键字,在栈索引位置( -2)的表(table)中查询该关键字的值(value),然后将栈顶的key出栈,再将value压栈。

3、最后一个lua_pop( L, 1)的作用就是将这个返回值出栈,以保持栈的原貌。

好好理解上面被标记为粗体的文字,因为这就是表的基本应用的全部--只是基本应用。

最后,我想谈谈为什么不能通过LuaEdit的语法检测。原因很简单:LuaEdit所使用的lua库中不包含我们写的这些个函数的声明---这就是为什么我说LuaEdit跟记事本没什么区别,事实上我除了学习Lua语法的阶段使用了它,现在一直都是用记事本在写脚本。当然,在研究Lua的同时,我也会尝试研究下LuaEdit的使用--因为它长的跟VS2005很象,呃...

分享到:
评论

相关推荐

    自我学习笔记--LUA;python:网络编程等

    【标题】中的“自我学习笔记--LUA;python:网络编程等”表明这是一份包含LUA和Python语言,特别是关于网络编程的学习资料。LUA和Python都是编程语言,广泛应用于游戏开发、脚本编写、自动化任务以及网络服务等领域。 ...

    lua基础学习笔记

    ### Lua基础学习笔记 #### 一、Lua简介与特点 Lua是一种轻量级且高效的脚本语言,广泛应用于游戏开发、网页应用、图形界面等领域。对于已有其他编程语言基础的学习者来说,掌握Lua通常较为迅速。Lua的设计哲学是...

    cocos2dx-lua 笔记

    理解 Lua 的基本语法,如变量、函数、表(数组)和面向对象编程是掌握 Cocos2d-x Lua 开发的基础。 三、Cocos2d-x Lua 整合 Cocos2d-x 提供了 Lua 脚本绑定,允许开发者用 Lua 编写游戏逻辑。通过 tolua++ 工具,...

    lua (vc环境)学习笔记(学习代码)

    **lua (VC环境) 学习笔记** 在深入学习lua编程语言并将其应用于Microsoft Visual C++(VC环境)时,我们需要了解几个关键知识点。lua是一种轻量级的脚本语言,设计目标是作为嵌入式语言,使得游戏开发、系统管理、...

    lua基础笔记

    Lua是一种轻量级的脚本...在实际应用中,理解并熟练运用这些知识能帮助开发者更好地利用Lua解决实际问题。不过,正如描述中提到的,任何学习资源都不可能十全十美,学习过程中还需要结合实践不断调整和完善自己的理解。

    G-series Lua API 参考文档.zip

    《G-series Lua API 参考文档》是针对罗技G系列设备的一份详细技术资料,主要介绍了如何使用Lua编程语言来操控和自定义这些设备的功能...无论是为了个性化设置还是提高游戏效率,投入时间学习和应用Lua API都是值得的。

    Lua基础应用笔记

    ### Lua基础应用知识点详解 #### 一、Lua简介与特性 ...以上内容覆盖了Lua的基本语法和常用操作,是学习Lua的入门必备知识点。对于从事Unity3D开发或者对Lua感兴趣的朋友来说,掌握这些内容将极大地提高编程效率。

    lua (vc环境)学习笔记

    【Lua (VC环境) 学习笔记】 Lua是一种轻量级的、开源的脚本语言,主要用于嵌入式系统和游戏开发。它以其简洁的语法、高效性和易于集成的特点受到广泛欢迎。在VC(Visual C++)环境中使用Lua,可以为C++应用程序提供...

    Cocos2D-X开发学习笔记-时间调度schedule函数的使用

    本篇学习笔记主要关注的是Cocos2D-X中的时间调度机制,特别是如何使用`schedule`函数进行周期性任务的执行。 在Cocos2D-X中,时间调度是游戏循环的重要组成部分,它允许开发者在特定的时间间隔内执行某些函数或操作...

    Redis学习笔记-包括周阳和狂神说

    在本“Redis学习笔记-包括周阳和狂神说”中,我们将深入探讨Redis的核心概念、功能特性以及实际应用。 1. Redis基本概念 - 键值对:Redis的核心数据结构,键是唯一的标识,值可以是多种类型,如字符串、哈希、列表...

    Lua使用笔记

    这个"Lua使用笔记"的压缩包包含了三个文件:hello3.lua、hello.lua和hello2.lua,这些文件很可能是 Lua 的示例代码或练习脚本,通过它们我们可以学习和理解 Lua 的基本语法和特性。 首先,我们来看一下 Lua 的基础...

    个人对c++使用lua的一些笔记

    在C++中集成Lua是一种常见的做法,用于在游戏开发、脚本系统和其他需要动态扩展性的应用中。Lua是一种轻量级的嵌入式脚本语言,它的语法简洁且易于学习,而C++则以其强大的性能和灵活性著称。将两者结合可以让我们在...

    STEP-BY-STEP--LUA.zip_lua_lua脚本_step by step

    "Lua脚本语方学习笔记,作为学习lua的参考" 描述了这个压缩包的内容是针对Lua脚本的学习资料,以笔记的形式记录,旨在为学习者提供参考,辅助他们系统地学习和理解Lua语言。 **标签解读:** "lua lua脚本 step_by_...

    Cocos2D-X开发学习笔记-渲染框架之图形的绘制

    Cocos2D-X是一款强大的跨平台2D游戏开发框架,基于C++,并提供了Lua和JavaScript等脚本语言接口。本教程将深入讲解Cocos2D-X中的渲染框架,特别是如何进行图形的绘制,这对于创建游戏场景、角色动画以及用户界面至关...

    redis心得笔记--180202

    - Lua脚本:支持在服务器端执行Lua脚本,进行复杂逻辑处理。 3. 使用场景 - 缓存:Redis常用于减轻数据库压力,提高网站性能。 - 排行榜:利用有序集合实现动态更新的排行榜功能。 - 分布式锁:通过设置过期...

    Cocos2d-x学习笔记

    - 学习脚本语言:虽然Cocos2d-x支持多语言开发,但了解JavaScript、Lua等脚本语言,可以快速实现游戏功能和逻辑。 Cocos2d-x框架除了Windows平台外,还支持iOS、Android、Mac OS X、Web等平台,初学者在掌握了...

    lua开发工具

    Lua是一种轻量级的脚本语言,广泛应用于游戏开发、嵌入式系统、服务器配置等领域。在开发过程中,选择合适的工具能够极大地提高效率和代码质量。本文将详细探讨Lua开发中的关键工具及其功能。 1. **集成开发环境...

    redis和lua

    Redis 和 Lua 是两种在 IT 领域广泛应用的技术。Redis 是一个开源的内存数据结构存储系统,常被用作数据库、缓存和消息中间件,而 Lua 是一种轻量级的脚本语言,广泛用于游戏开发、嵌入式系统以及各种软件中的扩展。...

    游戏开发学习笔记-2.引擎初现

    在这个“游戏开发学习笔记-2.引擎初现”中,我们将重点探讨游戏开发的基础——游戏引擎。 游戏引擎是游戏开发的核心工具,它提供了一整套功能,帮助开发者构建游戏世界、处理图形渲染、物理模拟、音频处理、输入...

    Cocos2d-android-1学习笔记

    这个“Cocos2d-android-1学习笔记”正是针对初学者或者正在深入学习Cocos2d-x在Android平台应用的开发者所准备的资料。 首先,笔记可能会涵盖Cocos2d-x的安装与环境配置,这包括下载源码、设置NDK路径、配置Android...

Global site tag (gtag.js) - Google Analytics