Lua笔记(5)——C API头文件简介

搭建Lua环境时,安装程序会把以下5个头文件拷贝到指定目录(默认为/usr/local/include/):

-rw-r--r--.  1 root root 14825 Jun  3 09:03 lua.h
-rw-r--r--.  1 root root 20581 May 20 13:39 luaconf.h
-rw-r--r--.  1 root root  8433 Oct 29  2014 lauxlib.h
-rw-r--r--.  1 root root  1173 Feb  6  2014 lualib.h
-rw-r--r--.  1 root root   191 Dec 22  2004 lua.hpp

先从最简单的lua.hpp来看:

// lua.hpp
// Lua header files for C++
// <<extern "C">> not supplied automatically because Lua also compiles as C++

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

可以看到lua.hpp只是包含了其它的几个头文件,供C++程序使用。

lua.h定义了Lua提供的最基本的功能:创建Lua环境,调用Lua函数,在Lua环境中读写全局变量等。lua.h定义的所有成员(包括函数,宏等)都是用lua_LUA_作为前缀。

lauxlib.h定义了Lua辅助库(auxiliary library)提供的的函数,这个文件里定义的成员都是以luaL_作为前缀。Lua辅助库在lua.h定义的基础API之上,又封装了一层API,以提供更好的通用性。Lua辅助库并不会访问Lua的内部,所有操作都是通过lua.h的基础API去操作。

luaconf.h会定义Lua环境的配置信息。

lualib.h定义了Lua语言标准库的名字,以及打开这些库的函数。

Lua笔记(4)——C API综述

Lua是一门嵌入式语言(embedded language),这就意味着Lua并不是一个独立(stand-alone)的包(package),而是一个可以供其它想使用Lua功能的程序链接的库(library)。实际上,Lua解释器程序lua(可执行文件)就是利用Lua库实现的一个小程序:读入文件或字符串,丢给Lua库去做处理。

Lua可以作为一个单独的库供其它程序使用以扩展其功能,因此可以被称之为“extension language”。同时,使用Lua的程序亦可以向Lua环境注册新的函数,这些函数用C(或其它语言)编写,提供一些不能由Lua直接实现的功能,所以Lua又是一门“extensible language”。

Lua作为extension language时,C代码作为控制,Lua作为库;而作为“extensible language”时,正好反过来,Lua代码作为控制,C作为库。CLua之间的接口称之为C API,它是一组供C访问Lua的函数。

C代码和Lua程序之间通过一个虚拟的栈(stack)来进行通信。几乎所有的C API调用都会访问栈上的数值,并且所有的C代码和Lua程序之间的数据交换都通过这个栈。另外,栈也可以用来保存一些临时数据。栈帮忙解决LuaC之间两个很重要的“impedance mismatch”问题:
a)Lua具有内存垃圾(garbage)回收机制,而C需要显示地释放;
b)Lua是动态类型(dynamic typing),而C是静态类型(static typing)。

Lua笔记(3)——table浅析

TableLua中一种重要的数据结构,可以将其视为关联数组(associate array),除了nil以外,数字,字符串,Lua语言中的其它值均可成为数组的keyLua也使用table来代表包(package)和对象(object)。比如io.read就可以理解为“io”模块的read函数。

TableLua中既不是“值(value)”,也不是“变量(variable)”,而是对象(object)——一个动态分配的对象。Table都是匿名的,程序只能通过“引用(reference)”(或称之为“指针”)来操作它。当程序中所有指向某个table的引用都无效后,Lua的垃圾回收程序会回收这个table的内存。程序没有办法声明(declare)一个table,而只能通过构造表达式(constructor expression)来创建一个table,就像这样:

a = {}

同全局变量一样,没初始化的table元素的值为空:

> a = {}
> print(a["x"])
nil

同样,把table元素的值设为nil就会删除这个元素。这并不是个巧合,其实在Lua中,全局变量就是存在一个table里。

使用table时,要注意table["name"]table.nametable[name]三者的区别。其中table["name"]table.name是一样的,tablekey都是"name"这个字符串。而table[name]key则是name变量的值。参考下面这个例子:

> name = "a"
> table["name"] = 10
> table[name] = 20
> print(table["name"])
10
> print(table.name)
10
> print(table[name])
20
> print(table["a"])
20

使用整数作为key,就可以让table变成通常意义上的数组(array)或列表(list)。需要额外注意的是,在 Lua中,使用1(不是0)来索引数组第一个元素,这个一定要注意!!

如果一个列表中间没有“洞”,即nil元素,则称之为序列(sequence),对于序列,可以使用长度运算符#获得序列的长度:

> a = {}
> a[1] = 10
> a[2] = 20
> print(#a)
2