0基础lua学习(十七)C调用Lua----01小demo

来源:互联网 发布:其待君王乎 编辑:程序博客网 时间:2024/06/05 04:02

一、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将它从栈中删除。

三、你可以将 LuaC/C++

代码一起编译, lua.h 并不包含这些典型的在其他 C 库中出现的整合代码:

#ifdef __cplusplusextern "C" {#endif...#ifdef __cplusplus}#endif

因此,如果你用 C方式来编译它,但用在C++中,那么你需要象下面这样来包含lua.h
头文件。
extern "C" {#include <lua.h>}
一个常用的技巧是建立一个包含上面代码的 lua.hpp头文件,并将这个新的头文件包
含进你的
C++程序。


以上大部分是《Programming in Lua 》的缩略版,

概书在第24章 C API纵览,详细的介绍了这方面内容,过于细致,所以我精简了一部分,外加自己的一些补充。


原创粉丝点击