一、Lua介绍
Lua 是一个嵌入式的语言,Lua 解释器是一个使用 Lua 标准库实现的独立的解释器,她是一个很小的应用(总共不超过 500 行的代码)。解释器负责程序和使用者的接口:从使用者那里获取文件或者字符串,并传给 Lua 标准库, Lua 标准库负责最终的代码运行。
1.Lua 作为扩展性语言和可扩展的语言
Lua 可以作为程序库用来扩展应用的功能,Lua 程序中可以注册有其他语言实现的函数,这些函数可能由 C 语言(或其他语言)实现,可以增加一些不容易由 Lua 实现的功能。
2.C 和 Lua 中间有两种交互方式
- C 作为应用程序语言, Lua 作为一个库使用;
- 反过来, Lua 作为程序语言, C 作为库使用。
这两种方式, C 语言都使用相同的 API 与 Lua 通信,因此 C 和Lua 交互这部分称为 C API。
(C API 是一个 C代码与 Lua 进行交互的函数集。他有以下部分组成:读写Lua 全局变量的函数,调用 Lua 函数的函数,运行Lua 代码片断的函数,注册 C 函数然后可以在
Lua 中被调用的函数,等等。)
------------C API介绍-------------------------------------------------
C API 遵循C 语言的语法形式,这 Lua 有所不同。当使用 C进行程序设计的时候,我们必须注意,类型检查,错误处理,内存分配都很多问题。
API 中的大部分函数并不检查他们参数的正确性;你需要在调用函数之前负责确保参数是有效的。如果你传递了错误的参数,可能得到 \"segmentation fault\" 这样或者类似的错误信息,而没有很明确的错误信息可以获得。
另外, API重点放在了灵活性和简洁性方面,有时候以牺牲方便实用为代价的。一般的任务可能需要涉及很多个 API 调用,这可能令人烦恼,但是他给你提供了对细节的全部控制的能力,比如错误处理,缓冲大小,和类似的问题。
-------------------------------------------------------------
3.在 C 和 Lua 之间通信关键内容在于一个虚拟的栈。
几乎所有的API 调用都是对栈上的值进行操作,所有 C 与 Lua 之间的数据交换也都通过这个栈来完
成。另外,你也可以使用栈来保存临时变量。栈的使用解决了 C 和 Lua 之间两个不协调Programming in Lua
的问题:
第一, Lua 会自动进行垃圾收集,而 C 要求显示的分配存储单元,两者引起的矛盾。
第二, Lua 中的动态类型和 C 中的静态类型不一致引起的混乱。
~~以上摘自《Programming in Lua》
二、配置环境
1、首先下载lua for windows,我使用的是 Lua 5.1
2、在vs2015/vs2012/vs2010/VS2005上配置lua环境
I、添加lua头文件包含目录
项目->属性->配置属性->C/C++->常规->附加包含目录:C:\Program Files (x86)\Lua\5.1\include(根据你的lua安装路径设置)
II、添加静态库目录
项目->属性->配置属性->连接器->常规->附加库目录:C:\Program Files (x86)\Lua\5.1\lib(根据你的lua安装路径设置)
III、添加引用库
项目->属性->配置属性->连接器->输入->附加依赖库:lua51.lib
二、编写hello,world
1、新建一个空的win32工程(lua_test),添加一个源文件lua_test.cpp
2、用文本编辑器创建一个lua脚本(hello.lua),内容如下:
下面代码如果编译通过,说明调用成功
// prj.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <intrin.h>
int _tmain(int argc, _TCHAR* argv[])
{
char buff[256];
int error;
lua_State *L = lua_open(); /* opens Lua */
luaopen_base(L); /* opens the basic library */
luaopen_table(L); /* opens the table library */
luaopen_io(L); /* opens the I/O library */
luaopen_string(L); /* opens the string lib. */
luaopen_math(L); /* opens the math lib. */
while (fgets(buff, sizeof(buff), stdin) != NULL) {
error = luaL_loadbuffer(L, buff, strlen(buff),
"line") || lua_pcall(L, 0, 0, 0);
if (error) {
fprintf(stderr, "%s", lua_tostring(L, -1));
lua_pop(L, 1);/* pop error message from the stack */
}
}
lua_close(L);
return 0;
}
lua.h: 定义了 Lua 提供的基础函数。其中包括创建一个新的Lua 环境的函数
(如 lua_open),调用 Lua 函数(如 lua_pcall)的函数,读取/写入Lua 环境的全局变量
的函数,注册可以被 Lua代码调用的新函数的函数,等等。所有在 lua.h中被定义的都
有一个 lua_前缀。
lauxlib.h:定义了辅助库( auxlib)提供的函数。同样,所有在其中定义的函
数等都以 luaL_打头(例如, luaL_loadbuffer)。
ps:
Lua 库没有定义任何全局变量。它所有的状态保存在动态结构lua_State 中,而且指
向这个结构的指针作为所有 Lua 函数的一个参数。这样的实现方式使得Lua 能够重入
( reentrant)且为在多线程中的使用作好准备。
- 函数 lua_open 创建一个新环境(或state)。 lua_open创建一个新的环境时,这个环境并不包括预定义的函数,甚至是 print。
- 为了保持 Lua 的苗条,所有的标准库以单独的包提供,所以如果你不需要就不会强求你使用它们。头文件 lualib.h 定义了打开这些库的函数。例如,调用 luaopen_io,以创建io table 并注册 I/O 函数( io.read,io.write等等)到 Lua 环境中。
- 创建一个 state 并将标准库载入之后,就可以着手解释用户的输入了。对于用户输入的每一行, C 程序首先调用 luaL_loadbuffer 编译这些 Lua 代码。如果没有错误,这个调用返回零并把编译之后的 chunk压入栈之后, C程序调用 lua_pcall,它将会把 chunk 从栈中弹出并在保护模式下运行它。和luaL_laodbuffer 一样,lua_pcall 在没有错误的情况下返回零。
- 在有错误的情况下,这两个函数都将一条错误消息压入栈;我们可以用 lua_tostring来得到这条信息、输出它,用lua_pop 将它从栈中删除。
三、你可以将 Lua和C/C++
代码一起编译, lua.h 并不包含这些典型的在其他 C 库中出现的整合代码:
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif
因此,如果你用 C 方式来编译它,但用在 C++ 中,那么你需要象下面这样来包含 lua.h
头文件。
extern "C" {
#include <lua.h>
}
一个常用的技巧是建立一个包含上面代码的
lua.hpp
头文件,并将这个新的头文件包含进你的 C++ 程序。
以上大部分是《Programming in Lua 》的缩略版,
概书在第24章 C API纵览,详细的介绍了这方面内容,过于细致,所以我精简了一部分,外加自己的一些补充。