https://www.cnblogs.com/dimin/p/7838674.html

https://blog.csdn.net/nekocode/article/details/7960371

lua与C/C++交互,主要靠lua API和向lua注册好的函数。如下图

注:LuaGlue就是让Lua脚本中可调用的C++函数的接口。即那些注册的函数。

这里起关键作用的要数lua_State的结构,这就得讲一下Lua环境和Lua Stack。

Lua环境

Lua环境由所有可操作的数据构成,如编译好的函数、变量以及其他运行时内存。这些数据保存在一个称做lua_State的结构中。所有Lua应用程序都要求至少有一个lua_State,如果需要还可以有多个(如需要为两个不同的系统保存不同的数据时)。

Lua Stack

对于我们来说,Lua环境是用来发送和接收数据的地方,它利用栈(Lua Stack)来达到该目的。所有的数据交换,无论是Lua到C/C++语言或C/C++语言到Lua都通过这个栈来完成。Lua栈不同于系统栈,它只能通过Lua的API函数访问。

注册到Lua中的函数

所有注册到Lua中的函数都具有相同的原型

typedef int (*lua_Function)(lua_State *L);

这个函数仅有一个参数,即Lua的状态。它返回一个整数,表示其压入栈中的返回值数量。因此函数无须在压入结果前清空栈。在它返回后,Lua会自动删除栈中结果之下的内容。

在Lua使用这个函数前,必须注册这个函数。

void lua_pushcfunction (lua_State *L, lua_CFunction f);

将一个 C 函数压入堆栈。 这个函数接收一个 C 函数指针,并将一个类型为 function 的 Lua 值 压入堆栈。当这个栈顶的值被调用时,将触发对应的 C 函数。

这种方法需要重新编译Lua的执行程序,才能在Lua程序中使用这个新函数。但用下面的方法会更好,直接将C函数链接到lua。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Lua调用C函数时,并不依赖于函数名、包的位置或可见性规则,而只依赖于注册时传入的函数地址。当用C函数扩展Lua时,最好将代码设计为一个C模块。因为现在只注册一个函数,但说之后可能会需要更多的函数。辅助库为这项工作提供了一个函数luaL_register,这个函数接收一些C函数及其名称,并将这些函数注册到一个与模块同名的table中。例如,假设创建一个模块,其中包含了这个luaglue函数。首先,必须定义这个模块函数:

static int luaglue(lua_state *L)
{
}

然后,声明一个数组,其中包含模块中所有函数及名称。这个数组元素的类型为luaL_Reg结构,该结构有两个字段,一个字符串和一个函数指针:

static const struct luaL_Reg mylib[] = {
{"dir",l_dir},
{NULL,NULL}//结尾
};

最后,声明一个主函数,其中用到了luaL_register:

int luaopen_mylib(lua_State *L)
{luaL_register(L,"mylib",mylib);return 1;
}

其中luaL_register原型为:

void luaL_register (lua_State *L,const char *libname,const luaL_Reg *l);

luaL_register根据给定的名称(“mylib”)创建(或复用)一个table,并用数组mylib中的信息填充这个table。在luaL_Register返回时,会将这个table留在栈中。最后,luaopen_mylib函数返回1,表示将这个table返回给Lua。

ps:打开一个库,当libname为null时,该函数注册所有在luaL_Reg上的函数,不为null时,该函数会创建一个table,根据libname注册不与libname关联的函数。

当写完c模块后,必须将其链接到解释器。如果Lua解释器支持动态链接的话,那么最简便的方法是使用动态链接机制。在这种情况中,必须将c代码编译成动态链接库,并将这个库放入C路径(LUA_CPATH)中。然后,便可以用require从Lua中加载这个模块:

require "mylib"

这名调用会将动态库mylib链接到Lua,并会寻找luaopen_mylib函数,将其注册为一个Lua函数,然后调用它以打开模块。

如果解释器不支持动态链接,那么就必须用新的模块来重新编译Lua。此外,还需要以某种方式来告诉解释器,它应在打开一个新状态的同时打开这个模块。最简单的做法是,将luaopen_mylib加到luaL_openlibs会打开的标准库列表中,这个列表在文件linit.c中。

从C++程序员的观点来看,Lua像一个“黑盒子”,为一些服务处理命令和调用。Lua通常作为最上层接口直接和程序使用者和游戏玩家打交道,在核心程序处理之前接受并响应输入。

如果嫌麻烦,不想手动写这些代码的话,我推荐lua_tinker。也就只有两个文件,lua_tinker.h,lua_tinker.cpp。

环境配置,首先你需要搭建一个可以用lua的开发环境,这里网上有很多,我就不多说了。然后再将lua_tinker的lua_tinker.h和lua_tinker.cpp添加到你的工程中就可以了。

lua_tinker::def(L, "cpp_func", cpp_func); //在L栈中注册C++函数
lua_tinker::dofile(L, "sample1.lua"); //加载lua文件
int result = lua_tinker::call<int>(L, "lua_func", 3, 4); //调用lua中的function lua_func

lua_tinker::class_add(L,"classA");//在lua中注册类
lua_tinker::class_con(L,lua_tinker::constructor<classA>);//在lua中注册构造函数
lua_tinker::class_mem(L,"memName",&classA::memName);

ps:用lua_tinker::call是要注意,参数不支持智能指针

转载于:https://www.cnblogs.com/losophy/p/9257825.html

lua:lua与C/C++程序的整合相关推荐

  1. 浅谈 Python 程序和 C 程序的整合

    浅谈 Python 程序和 C 程序的整合 Python 是一种用于快速开发软件的编程语言,它的语法比较简单,易于掌握,但存在执行速度慢的问题,并且在处理某些问题时存在不足,如对计算机硬件系统的访问, ...

  2. 桌面虚拟化之应用程序的整合

    摘要:  从去年下半年开始,桌面虚拟化市场越来越火,很多客户 咨询桌面虚拟化方案,很多人开口都是"桌面云",但是应用程序 的整合决定了桌面虚拟化项目的成败,如果这个环节处理不好,会 ...

  3. 第三方程序完美整合phpwind8的UC用户中心-教程加P8

    不管phpwind未来路如何走我们都会永远支持!!本教程分析 phpwind的UC用户中心如何整合,和提供从P8分离后的完整P8UC整合接口包. P8UC作用: P8的UC与其它程序的UC通信原理基本 ...

  4. lua运行外部程序_Lua 协同程序(coroutine)

    coroutine.creat方法只要建立了一个协程 ,那么这个协程的状态默认就是suspend.使用resume方法启动后,会变成running状态:遇到yield时将状态设为suspend:如果遇 ...

  5. Lua === Lua 十分钟基础入门上手

    Lua维基百科 Lua的目标是成为一个很容易嵌入到其他语言中使用的语言: 很多程序员使用Lua作为自己的嵌入式脚本语言,实现可配置性,可扩展性: 轻量级语言,体积小速度启动快,只包含一个精简的核心和基 ...

  6. [Lua]Lua入门教程

    什么是Lua Lua 是一个小巧的脚本语言.是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由Rober ...

  7. LUA———Lua和C 区别

    1.lua和c有两种关系: 一种是在lua中调用C的函数,C称为库代码,一种是C中调用lua,C就称为应用程序代码,此时C中包含了lua的解释器.注意在C++中,通常要把lua的一些头文件定义在ext ...

  8. C# ASP.NET程序员整合Java门户单点登录PHPwind论坛博客软件集成项目经验总结

    为什么80%的码农都做不了架构师?>>>    有人曾问,如何正确估算项目周期?你是天天写C#程序的程序员,若做了一个 PHPwind 的单点登录,那估计需要几天时间? 客户只提了一 ...

  9. LUA: lua基础.

    2019独角兽企业重金招聘Python工程师标准>>> nil :它是一个类型且只有一个值nil.它的主要功能是区别于其他任何值.如果对一个全局变量赋值nil等同于删除它. 条件测试 ...

最新文章

  1. c语言中不能表示的整型常量进制,C语言中整型常量的表示方法
  2. git 添加未跟踪的文件
  3. Ruby on Rails 的检验方法(Validation Helpers)大全
  4. 【JVM系列】一步步解析java执行内幕,java初级面试笔试题
  5. 工作日历计划javaweb_将你的日历与 Ansible 集成,以避免与日程冲突 | Linux 中国...
  6. windows下sublime2 clojure环境配置
  7. spark写入数据到elasticsearch
  8. 关于ie7下display:inline-block;不支持的解决方案。
  9. 小白学习Python的一点建议
  10. 微信小程序登陆界面(效果图+源代码)
  11. 显示器刷新率测试软件144,【显示器】为什么“吃鸡”要选144Hz显示器?详解高刷新率显示器对FPS游戏的重要影响...
  12. 资源共享(不限领域,持续更新)
  13. freeswitch exporter
  14. 道格拉斯简化_简化组织变革:困惑的指南
  15. VMware虚拟机鼠标失灵怎么办
  16. 机器学习——激活函数sigmoid、tanh、ReLU和softmax
  17. 巨杉数据库基于mysql_【巨杉数据库SequoiaDB】巨杉Tech |巨杉数据库的HTAP场景实践...
  18. 新型能力的分解与组合
  19. 第一章、linux入门及基本命令(案例讲解)
  20. python 判断是否有某个属性_python如何判断对象的某个属性

热门文章

  1. Project2007企业项目管理实践
  2. ubuntu 解压文件
  3. 刚构桥的优缺点_钢结构桥梁的优缺点!!
  4. 到哪里下载专业所需的各种软件
  5. iOS16系统手机设置开启开发者模式才能安装ipa包
  6. Exchange 2k的安装与删除。
  7. Android4.2.2 Gallery2源码分析(2)——发现Gallery.java
  8. 如何快速制作脚本?间隔时间自动使用按键精灵游戏技能辅助脚本
  9. 2021春运购票日历
  10. win10系统word2016打开出现运行时错误 “429 ActiveX部件不能创建对象” 的解决方法!