Lua学习笔记二之C中调用Lua

Lua学习笔记--C调用Lua Lua是一种嵌入式语言,可以很好的嵌入其他应用程序。lua为我们提供了一组灵活的C API,使C代码能够很好的与Lua进行交互。包括读写Lua全局变量,调用Lua函数,运行Lua代码,注册C函数反过来供Lua调用。简单的说,C能调用Lua,反过来Lua也能调用C。真的是灰常强大灵活的脚本!!现在,先来学习一下怎么用C调用Lua。 其实最简单的我们已经做过了,通过一个dofile,运行一个lua 阅读详情
     虽然之前看过《Lua程序设计》(第二版)这本书,但对C与Lua交互的部分,一直不是很理解。最近想系统学习和深入理解C与Lua的交互(实质是想通过这个,进一步阅读Lua源码,:)),因此又看了一下这本书的第4部分,下面是在学习C中调用Lua的全局变量、table和函数的笔记以及自己的理解,其中学习过程中的写的测试代码可以从我的GitHub下载。

     0、Lua与C有两种交互形式。在第一种形式中,C语言拥有控制权,Lua是一个库,这种形式中的C代码称为“应用程序代码”;在第二种形式中,Lua拥有控制权,这种形式中的C代码称为“库代码”。Lua的解释器程序(lua.c)就是“应用程序代码”的一个实例;而Lua标准库(lstrlib.c,lmathlib.c等)则是“库代码”的实例。 应用程序代码和库代码(注意他们都是C代码,只是功能或者说地位不同)都使用通用的API来与Lua代码通信,这些API称为C API。

      1、lua源码头文件lua.h中,定义了向C应用程序提供的基础函数,包括创建lua环境,调用lua函数(如lua_pcall)、读写Lua环境中的全局变量,以及注册供Lua调用的新函数等。lua.h中声明或定义的函数名都以lua_作为前缀。
     
     2、头文件lauxlib.h定义了辅助库(auxiliary library, auxlib)提供的函数。在该文件中所定义的函数名都以luaL_作为前缀。该辅助库所有函数的实现,都只是用到lua.h中声明的函数,也就是说,该辅助库中所有的函数实现不会直接访问Lua的内部,该库相对于是一个较高的抽象,用于侧重于解决具体任务。

     3、 Lua库中没有定义任何全局变量。它将所有的状态都保存在动态结构lua_State中,所有的C API都要求传入一个指向该结构的指针。

     4、在Lua与C之间交换数据时,主要有两个问题,一个是动态类型和静态类型之间的区别,其次是自动内存管理和手动内存管理之间的区别。为了解决两个问题,Lua与C之间交换数据时利用了一个抽象的栈。

     5、Lua中的字符串不是以零结尾的,他们可以包含任意二进制数据。因此,它们必须同时保存一个显示的长度。将字符串压入栈中的基本函数是lua_pushlstring,它要求传入一个显示的长度参数。对于零结尾的字符串,可以使用函数lua_pushstring,这个函数通过strlen来计算字符串的长度。Lua不会持有指向外部(指Lua虚拟机外的)字符串的指针。对于所有Lua持有的字符串,它都会生成一个内部副本,或者复用现有的内容。因此,即使在这些函数立即返回后立刻释放或修改这些字符串,也不会出现问题。

     6、接口中以lua_push*开头的函数,一般用来向栈中压入函数,通常Lua代码调用C函数时,调用的函数通常就用这些接口,把结果压入栈中,返回给lua(当然这些C函数也要求返回一个值,告诉Lua一共返回(压入)了多少个值)。值得注意的是,向栈中压入一个元素时,应该确保栈中具有足够的空间,可以调用lua_checkstack来检测是否有足够的空间。

     7、接口中以lua_to*开头的函数,一般用于栈中获取一个值。通常在C函数中,可以用这些接口获取从lua中传递给C函数的参数。如果指定的元素不具有正确的类型,调用这些函数也不会出问题的。在这种情况下,lua_toboolean、lua_tonumber、lua_tointeger和lua_objlen会返回0,而其他函数会返回NULL。对于返回NULL的函数,可以直接通过返回值,即可以知道调用是否正确;对于返回0的函数,通常先需要使用lua_is*函数,看判断调用是否正确。

     8、接口中以lua_get*开头的函数,调用后,一般会向栈顶中压入一个元素。比如void lua_gettable(lua_State *L,int index)会向栈顶压入t[k],这里的t是栈中索引为index的值,k是栈顶的值。

     9、接口中以luaL_check*开头的函数,如果发生错误,则总是抛出一个错误。若正确,则会返回相应类型的值,该接口通常用来检测lua传入的参数是否正确。


    10、 当Lua调用的一个C函数返回时,Lua就会清空它的栈。也就是说在Lua代码中调用C函数时,当这个C函数返回后,Lua虚拟机就会把其相应的交换数据的栈清空。也说明了,对被调用的C函数,从栈中获取的值,但C函数返回后,就不能再使用了(特别是针对接口lua_tolstring)。
     
     11、几乎所有的API函数都会抛出错误(即调用longjmp),而不是返回错误。当编写库代码时(被Lua调用的C函数),使用longjmp几乎和使用异常处理机制一样方便,Lua会捕获所有可能的错误。而当编写应用程序代码时(调用Lua的C代码),必须提供一种捕获错误的方式。在大多数应用程序中,通常都通过调用lua_pcall来运行Lua代码,这样即使发生错误了,应用程序(比如游戏主进程)也不会结束。如果要保护那些与Lua交互的C代码,可以使用lua_cpcall。这个函数类似于lua_pcall,但它接受一个C函数作为参数,然后调用这个C函数。

     12、在调用lua_pcall时,第三个参数是期望的结果数量。就像lua的赋值一样,lua_pcall会根据要求的数量来调整实际结果的数量,即压入nil或丢弃多余的结果。在压入结果前,lua_pcall会先删除栈中的函数及其参数。如果一个函数会返回多个结果,那么第一个结果最先压入。

     13、可以使用luaL_checktype函数确保给定参数具有特定的类型,否则它会引发一个错误。
Lua与C/C++交互——Lua调用C/C++ Lua与C/C++交互——Lua调用C/C++ 0.简介          Lua(念“鲁啊”)作为一门发展成熟的脚本语言,正在变得越来越流行。它也可以作为和C/C++执行脚本交互的语言。并且Lua的整个库很小,我安装了最新的正式版Lua 5.1版本,而整个静态链接的lu 阅读详情

相关推荐

lua与C(一):C调用lua

lua和c有两种关系:       一种是在lua调用C的函数,C称为库代码,一种是C中调用lua,C就称为应用程序代码,此时C中包含了lua的解释器    C代码部分        注意在C++中,通常要把lua的一些头文件定义在extern “c”中,因为他们是C语言实现的。     1.  作为应用程序调用lua代码: char* buffer="print(\"hello,

leon 1万+

c调用lua

1.版本 1.1vs版本 vs2013 1.2lua版本 lua5.1,用luaForWindow安装 2.c调用lua 2.1编写lua代码 callLuaTest.lua function add(a,b) return a+b; end function sub(a,b) return a-b; end 然后把lua文件复制到项目目录下。 2.2复制头文件 vs创建控制台程序,在lua的安装目录下有个include文件夹,里面含有C API的相关头文件,我的路径为C:\Progra

lemon 1261

Lua 语言】Lua 调用 C 函数

Lua 提供了调用 C 函数的接口,这样我们可以开心地用 C 来写一些底层的代码供 Lua 调用了。调用方式如下:1. 新建 C 源文件,将需要被 Lua 调用的函数实现如下:static int l_add(lua_State *L){    return 0;}...

appleeated的博客 1736

在C中调用Lua代码

这个程序从终端读入内容,而后按照lua块执行。 #include #include #include "lua.h" #include "lauxlib.h" #include "lualib.h" int main(){ char buff[1024]; int error; memset(buff, 0, sizeof(buff)); lua_Stat

博观约取 1966

C调用Lua函数

一:lua代码部分:新建一个lua文件,命名为HelloWorld.lua,代码如下: BoyName = "jon" local like = "apple" local function Hello(name, like)     print(string.format("Hello, %s!, you like %s", name, like)) end 里面包含了一

游子的博客 1599

C中调用Lua函数

我们先来看一个简单的例子: lua_State* L = NULL;// 内部调用lua函数 double f(double x, double y) { double z; lua_getglobal(L, "f"); // 获取lua函数f lua_pushnumber(L, x); // 压入参数x和y lua_pushnumbe...

weixin_34077371的博客 371

c调用lua详解(Windows版+Linux版)

1.c调用lua的实现原理 lua语言是c语言实现的,而且是非常轻量级的,非常适合内存受限的嵌入式产品 c调用lua,需要在c程序中模拟出lua解释器环境,所以需要调用lua的函数,即生成c程序必定要链接lua库,lua解释器和C是通过一个虚拟来交换数据的 的大小可以设置,通过查看lua的源码,可以知道这个的大小,在luaconf.h的LUAI_MAXSTACK,还可以通过lua_...

follow_blast的博客 5718

Lua与C语言的互相调用

Lua底层是C语言开发的,在设计时就考虑到了与C语言的互操作性。可以把Lua作为一种独立的语言或者作为一种嵌入式的脚本语言。有许多游戏和其他应用程序利用Lua作为脚本语言。 在本文中,我们将重点探讨如何将Lua嵌入到C或C++应用程序中,作为胶水脚本存在。虽然此文只关注C语言的API,但在LuaDardo项目中,这些C API并没有做根本改变,只是在命名规范上做了适应Dart语言的变化(驼峰命名法)。简单说,LuaDardo基本是兼容这些API的。 使用 C API Lua的C语言API是高效和轻量级的。在

编程之路的专栏 7675

【C & Lua】C调用Lua | Lua调用C

Lua与C交互是一种非常常见的技术,它可以让我们在C语言中调用Lua脚本,也可以让我们在Lua脚本中调用C语言函数。这种交互方式可以使得我们在不同的编程语言之间实现混合编程,从而达到更高的灵活性和效率。LuaLua与C交互的核心数据结构,所有的数据交互都是通过Lua来完成的。无论是从Lua调用C函数,还是从C中调用Lua函数,都需要使用Lua来传递参数和返回值。

Cauchy的博客 2659

[LUA学习笔记03]LUA函数和C函数的相互调用

  1. 简介LUA和C之间的函数调用也是基于上一节提到的。 1.1 从C程序调用LUA函数LUA的函数和普通变量一样也是First Class Variable类型,可以看作函数指针变量参与操作。因此调用过程分为如下几个步骤: 请求LUA函数(指针)入(GLOBAL)。 将函数需要的参数入,入顺序按照参数被声明的顺序。 告知LUA

MrTECHNO的编程日记 7949

Lua调用c模块

一、lua调用c模块总结 1.c函数库成为lua的一个模块 主要做法:将包含c函数的代码生成库文件 linux下是.so windows下是.dll 同时拷贝到lua运行环境的bin下(由于我用的是LuaTool运行环境 所以放在bin下 程序运行默认从bin下找) 这样lua解析器才可以找到.dll文件 2.编写c模块 (1)先编写需要注册的c函...

小不点的博客 9880

Lua调用C函数

Lua调用C函数Lua利用一个虚拟的堆来给C传递值或从C获取值1. C函数作为应用程序的一部分2. C函数库成为Lua的模块Lua调用C函数Lua调用c模块 https://www.cnblogs.com/sifenkesi/p/3876745.html https://blog.csdn.net/liu943367080/article/details/90909005 Lua利用一个虚拟的堆来给C传递值或从C获取值 Lua利用一个虚拟的堆来给C传递值或从C获取值。每当Lua调用C函数,都会获得

宁静致远的博客 3899

C语言调用lua实例(简单上手)

C语言调用lua实例安装lua环境DEMOlua脚本(实现两个数的相加):C语言调用lua函数 安装lua环境 Ubuntu下lua环境安装。 Lua是一种嵌入式脚本语言,即Lua不是可以单独运行的程序,在实际应用中,C/C++作为主程序,调用Lua代码,此时可以将Lua看做“可扩展的语言”,我们将这种应用称为“应用程序代码”。 DEMO lua脚本(实现两个数的相加): --实现两个数的相加 function add(x, y) return x + y; end C语言调用lua函数 #inc

一只青木呀 3351

C语言中调用LUA(1)

C程序中调用LUA脚本文件 1,新建LUA脚本  test.lua   print("hello world")   2,在C程序中调用   #include<stdio.h> #include<lua.h> #include<lualib.h> #include<lauxlib.h> int main(void) { //...

Eric_ 1317

深入理解Lua的闭包一:概念、应用和实现原理

本文首先通过的例子讲解了Lua中闭包的概念,然后总结了闭包的应用场合,最后探讨了Lua中闭包的实现原理。 闭包的概念 在Lua中,闭包(closure)是由一个函数和该函数会访问到的非局部变量(或者是upvalue)组成的,其中非局部变量(non-local variable)是指不是在局部作用范围内定义的一个变量,但同时又不是一个全局变量,主要应用在嵌套函数和匿名函数里,因此若一个闭包没有会

MaximusZhou的专栏 3万+

深入理解Lua的全局变量_G以及源码实现

Lua脚本层,Lua将所有的全局变量保存在一个常规的table中,这个table被称为全局环境,并且将这个table保存在一个全局变量_G中,文章首先通过一个递归函数,打印出_G中所有的信息,然后说明了怎么使用全局变量_G,最后从源码角度来看_G的实现

MaximusZhou的专栏 1万+

Lua中的线程和状态

线程(thread)作为Lua中一种基本的数据类型,它代表独立的执行线程(independent threads of execution),线程类型是实现协程(coroutines)的基础。本文将介绍Lua虚拟中的全局状态和线程的关系,以及从源码角度来看其数据结构。

MaximusZhou的专栏 1万+

LuaBridge为Lua绑定C/C++对象

最近为了总结Lua绑定C/C++对象的各种方法、第三方库和原理,学习了LuaBridge库为Lua绑定C/C++对象,下面是学习笔记,实质是对该库的Reference Manual基本上翻译了一遍,学习过程中测试代码,放在我的github上。 LuaBridge的主要特点      源码只有头文件,没有.cpp文件,没有MakeFile,使用时只需一个#include即可。      支

MaximusZhou的专栏 1万+
上一篇: Lua源码剖析(lstrlib.c)
下一篇: Lua学习笔记三之从Lua中调用C
MaximusZhou
博客等级 码龄15年 123粉丝 38原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值