http://blog.csdn.net/wildfireli/article/details/22307635

  Lua生来就是为了和C交互的,因此使用C扩展Lua或者将Lua嵌入到C当中都是非常流行的做法。要想理解C和Lua的交互方式,首先要回顾一下C语言是如何处理函数参数的。

C函数和参数
  大家知道C语言是用汇编实现的,在汇编语言中可没有函数的概念,与函数对应的是叫做子过程的东西,子过程就是一段指令,一个子过程与它调用的子过程之间通
过栈来进行参数的传递交互。在一个子过程在调用别的子过程之前,会按照约定的格式将要调用的子过程需要的参数入栈,在被调用的子过程中,可以按照约定的规
则将参数从栈中取出。同理,对于返回值的传递也同样是通过堆栈进行的。C语言约定的参数放入栈中的格式,就是“调用惯例”。C语言的函数原型则决定了压入
栈中的参数的数量和类型。


Lua的虚拟堆栈

  Lua和C之间的交互巧妙的模拟了C语言的堆栈,Lua和C语言之间的相互调用和访问都通过堆栈来进行,巧妙的解决了不同类型之间变量相互访问的问题。具体的,我们想象如下一个图

  +-------+                      +-------+
| | | |
| | +-------+ | |
| C | <==> | | <==> | Lua |
| Space | |Virtual| | Space |
| | | Stack | | |
| | | | | |
+-------+ +-------+ +-------+

  由于C和Lua是不同层次的语言,因此C语言的变量和Lua中的变量以及函数不能直接的交互,我们假定C语言和Lua都有自己的“空间(C Space和Lua Space)”。而这两个空间之间的交互就通过上图中的这个虚拟堆栈来解决。为何采用虚拟堆栈的方式来进行交互呢?其目的是在提供强大的灵活性的同时避免 交互时两种语言变量类型的组合爆炸。

C语言读写Lua全局变量(基本类型)
  C语言读取Lua的全局变量是一种最简单的操作。通过上图我们可以猜测到,如果通过C语言读取Lua中的全局变量需要两步:1、将全局变量从Lua
Space压入虚拟堆栈;2、从堆栈将全局变量读取到C语言Space中。在Lua和C的交互中,Lua无法看到和操作虚拟堆栈,仅在C语言中有操作堆栈
的权利,因此前面说到的两步全都是在C语言中完成的。我们看一个简单的例子


Lua代码:

global_var1 = ;
print("Print global varb from lua", global_var1);


C代码:

void get_global(lua_State *L)
{
int global_var1;
lua_getglobal(L, "global_var1"); /* 从lua的变量空间中将全局变量global_var1读取出来放入虚拟堆栈中 */
global_var1 = lua_tonumber(L, -); /* 从虚拟堆栈中读取刚才压入堆栈的变量,-1表示读取堆栈最顶端的元素 */ printf("Read global var from C: %d\n", global_var1);
}


执行结果:

  Lua中对堆栈的操作都是通过索引来进行的,索引为1表示从栈底数第一个元素,索引为2表示从栈底数第二个元素;同样也可以使用负数从栈顶开始计算,-1
表示从栈顶数第一个元素,-2表示从栈顶数第二个元素。更多堆栈的操作函数请参考lua的官方手册http://www.lua.org/manual
/5.2/manual.html。
同样从堆栈中获取元素,除了我们使用的lua_tonumber之外,还有lua_tolstring,lua_toboolean等。
  通常情况下在读取变量之前还需要对堆栈中元素的实际类型做出检查:

void get_global(lua_State *L)
{
int global_var1;
lua_getglobal(L, "global_var1"); /* 从lua的变量空间中将全局变量global_var1读取出来放入虚拟堆栈中 */
if (!lua_isnumber(L, -)) /* 检查堆栈中栈顶第一个元素是否是数字 */
error(L, "Is not number.");
global_var1 = lua_tonumber(L, -); /* 从虚拟堆栈中读取刚才压入堆栈的变量,-1表示读取堆栈最顶端的元素 */
}

写入全局变量也一样简单: 首先将数据压入堆栈,然后再将堆栈中的数据存入全局变量。
C代码:

void set_global(lua_State *L)
{
  lua_pushinteger(L, );
  lua_setglobal(L, "global_var1");
  printf("set global var from C:9\n");
}

cococs C++--------------------------------------------------------------------------------与Lua

  虽然终极方法是用bindings-generator脚本来注册C++类进Cocos2d-x的Lua环境,但理解toLua++本身的用法还是狠有必要的,只有知道了toLua++原本的用法,才能更好地理解Cocos2d-x是怎么把自己的C++类都注册进Lua环境的,这不仅能让编程时的思路更加 清晰,也能为日后在源码中寻找各种接口文档的过程中不至于看不懂那一大堆tolua_beginmodule、tolua_function是什么 意思。影响程序员学习提高的一大障碍就是忽略那些一知半解的代码,不去刨根究底地搞明白。

使用toLua++的标准做法是:

1、准备好自己的C++类,该怎么写就怎么写

2、仿造这个类的.h文件,改一个.pkg文件出来,具体格式要按照toLua++的规定,比如移除所有的private成员等

3、建一个专门用来桥接C++和Lua之间的C++类,使用特殊的函数签名来写它的.h文件,.cpp文件不写,等着toLua++来生成

4、给这个桥接的C++类写一个.pkg文件,按照toLua++的特殊格式来写,目的是把真正做事的C++类给定义进去

5、在命令行下用toLua++生成桥接类的.cpp文件

6、程序入口引用这个桥接类,执行生成的桥接函数,Lua环境中就可以使用真正做事的C++类了

编译---------------------------------------

在LUA的官网下载LUA源码后会有SRC文件夹

其中 lua.c 和 luac.c 都有 int main 函数,各源文件从根节点互相引用,可以将其编译为库 或 .exe使用,或将源码添加到项目里(要放到根目录)。

lua.c的main是编译运行时用的

luac.c的main是编译一个将lua代码编译成二进制代码的软件用的

luaconf.h 有个 LUA_BUILD_AS_DLL 用于编译windows动态链接库.dll文件

lua与C/C++交互概要的更多相关文章

  1. Lua与C的交互

    Lua 与 C 的交互 Lua是一个嵌入式的语言,它不仅可以是一个独立运行的程序,也可以是一个用来嵌入其它应用的程序库. C API是一个C代码与Lua进行交互的函数集,它由以下几部分构成: 1.  ...

  2. cocos2d-x lua与c++简单交互

    cocos2d-x lua与c++简单交互 version: cocos2d-x 3.6 本文讲述lua与c++的一些简单交互: lua通过消息方式调用c++无参接口 c++调用lua带参接口 1.通 ...

  3. Lua与C/C++交互问题

    初学lua,遇到注册C/C++交互函数问题 在lua与C/C++交互时,C/C++的注册Lua函数若是一个有返回类型(压栈)而不是获取类型的时候应该返回1而不是返回0,否则会出现在Lua中值为nil( ...

  4. Lua与C++的交互

    这篇文章说的挺详细的:Lua与C++的交互

  5. 通过lua栈了解lua与c的交互

    lua是如何执行的 其中分析.执行部分都是c语言实现的. lua与c的关系 lua的虚拟机是用c语言实现的,换句话说一段lua指令最终在执行时都是当作c语言来执行的,lua的global表,函数调用栈 ...

  6. Lua脚本和C++交互(一)

    现在,越来越多的C++服务器和客户端融入了脚本的支持,尤其在网游领域,脚本语言已经渗透到了方方面面,比如你可以在你的客户端增加一个脚本,这个脚本将会帮你在界面上显示新的数据,亦或帮你完成某些任务,亦或 ...

  7. Lua基本语法-lua与C#的交互(相当简单详细的例子)

    lua脚本 与 C#的交互 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Lua And C# -- ...

  8. lua和C++的交互(1)

    /* 以前听的一个故事,当年Java的创造者讲课的时候,一开始先拿一个简单的不能简单的小例子, 不断的扩展,最后成为一个复杂而完美的程序. 一个重要之重要的概念,就是栈.Lua与别的语言交互以及交换数 ...

  9. lua与c的交互(函数专用)

    Lua与C的交互 Lua是一个嵌入式的语言,它不仅可以是一个独立运行的程序,也可以是一个用来嵌入其它应用的程序库. C API是一个C代码与Lua进行交互的函数集,它由以下几部分构成: 1.  读写L ...

随机推荐

  1. 组件之间的数据传递--Vuex

    安装Vuex: npm install Vuex -S 在main.js中引入 import Vue from 'vue' import App from './App' import Vuex fr ...

  2. 加密解密DES之Android、IOS、C#实现

    Android实现 package com.sto.express.utils; import java.security.MessageDigest; import java.security.sp ...

  3. react-native中的navigator

    第一步安装相关插件 添加一些依赖 package com.awesomeproject; import com.facebook.react.ReactActivity; import com.fac ...

  4. snpeff注释变异(variants)

    1.进入网站http://snpeff.sourceforge.net/,下载snpeff: wget http://sourceforge.net/projects/snpeff/files/snp ...

  5. PHP中的数据结构:DS扩展

    PHP7以上才能安装和使用该数据结构扩展,安装比较简单: 1. 运行命令 pecl install ds 2. 在php.ini中添加 extension=ds.so 3. 重启PHP或重载配置 在这 ...

  6. 实现迁徙学习-《Tensorflow 实战Google深度学习框架》代码详解

    为了实现迁徙学习,首先是数据集的下载 #利用curl下载数据集 curl -o flower_photos.tgz http://download.tensorflow.org/example_ima ...

  7. 苹果电脑python3安装pillow模块

    我刚开始在苹果电脑自带的python 中安装了pillow模块,导致在后期我想在python3中安装pilow模块的时候 pip3 install pillow 但是总会提示错误说电脑中已经存在pil ...

  8. Android MVP 架构一 View与Presenter

    View:主要负责界面的显示及跟数据无关的逻辑,比如设置控件的点击事件等 Presenter:主要负责View与Model的交互 Model:数据部分 ------- MVP的核心是: View层不持 ...

  9. HTML学习笔记Day5

    一.CSS属性 1.文本溢出是否“...”显示属性:text-overflow:clip(不显示省略标记)/ellipsis(文本溢出时“...”显示) 定义此属性有四个必要条件:1)须有容器宽度:w ...

  10. vue实现购物车和地址选配

    参考文献        vue.js官网 项目演示:数据渲染,格式化数据,点击加,减号自动加减 项目准备 1. 项目css和js文件  https://github.com/4561231/hello ...