Lua与C C++的交互(一)

25 篇文章 4 订阅

一.概述

Lua是1993年由巴西里约热内卢天主教大学一个研究组开发的编程语言,算来是一种“中年”语言了,Lua用标准C语言编写并开源,其设计目的是为了嵌入应用程序中,因此Lua有几个特点:

  • 轻量级,Lua 是一种轻量小巧的脚本语言
  • 简洁,自动内存管理;只提供了一种通用类型的表(table)
  • 过程与函数式编程,不直接支持面向对象编程

最后一点, Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供功能,Lua可以使用它们,就像是本来就内置的功能一样,这也是本文所要讨论的。

由于Lua主要是做辅助性功能,Lua与C/C++交互也就只包含一种场景:C/C++是主程序,从C/C++中调用Lua脚本。

 

二.环境搭建

本文以linux ubuntu 17.10环境为例,windows类似。

目前Lua的版本是5.3.4.,由于Lua是纯ANSI C编写,因此由源代码编译非常简单,官网上也有编译好的,直接下载可用。Lua的源代码也不多,另一种办法可以直接在项目中嵌入源代码。

比较奇怪的是官网的makefile中只有生成静态连接库和命令行(运行程序)的,没有动态连接库,而下文的代码中恰恰需要动态连接库,因此这里需要修改一下官网的makefile。(另外,从网上下载的连接库,可能没有加-fPIC选项,连接到自己写的代码时,出现类似“Undefined reference “dlopen””这样的问题,官网的makefile也没有-fPIC选项,因此在编译动态库时会遇到“relocation R_X86_64_32 against symbol ‘…’”这样的错误,下面修改版的makefile中添加了这一选项)。

官网下的makefile(src目录下)比较长,以下只列出修改的部分:

1.修改  MYCFLAGS= 为 
MYCFLAGS=-fPIC

2.在LUA_A=liblua.a之前增加
LUA_SO= liblua.so

3.修改 ALL_T=$(LUA_A) $(LUA_T) $(LUAC_T) 为
ALL_T= $(LUA_A) $(LUA_SO) $(LUA_T) $(LUAC_T)

4.在$(LUA_A):命令块前增加一个命令块
$(LUA_SO): $(BASE_O)
         $(CC)-o $@ -fPIC -shared $? -ldl -lm

在linux下,编译命令为

make linux

由于两个命令行程序lua,luac需要用到gnu readline库,因此还需要预先安装此库,如果仅编译出lua的连接库,可不需要(修改makefile)

环境搭建好后,所有C/C++代码需要引用lua.hpp或lua.h, lualib.h, lauxlib.h,运行需要连接liblua.so。

三.虚拟栈

具体交互示例之前,先说明一下C/C++与Lua之间参数的传递机制:虚拟栈。

当Lua调用C函数时,会创建一个新栈(与其他栈不相关),这个栈就是C函数临时保存Lua参数的地方,包括Lua传递进来的参数以及C函数的返回参数。虽然这是一个栈,但为了方便,可以用索引来访问栈中的元素,索引可正可负,规则见下图。

缺省情况下,这个栈的大小至少可以保存LUA_MINSTACK(缺省是20)个元素。当C函数中需要多次压栈时,可用lua_checkstack来保证足够的栈空间。当C函数调用lua函数,lua函数有很多返回值时,lua保证栈的大小可容纳这些返回值,但不能保证还有空闲空间(即此时C函数再压栈时要注意栈空间)。
压栈有若干函数lua_pushXXX,出栈有一个lua_pop,也有一些栈元素操作的函数,如lua_rotate,lua_remove,lua_replace以及lua_setXXX等,它们可认为是helper函数。在写C代码与lua交互时,必须注意压栈与出栈的个数,好在lua reference manual中每个C API后都有[x,y,z]这样的说明,表明这个C函数的出栈个数x,压栈个数y,是否有抛异常z。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值