LuaC

lua: lua 5.2.3 http://www.lua.org/download.html

book: http://www.lua.org/pil/contents.html#P1

code: http://www.troubleshooters.com/codecorn/lua/lua_c_calls_lua.htm


一、测试环境搭建

1.生成liblua.a静态库

(0) xocde new project选择 

(1) OS X..Framework&Library..Library  

(2) Framework:None(Plain C/C++ Library) .. Type:Static

(3) 把 lua-5.2.3/src 里的 C 文件引入到新建的 xcode 工程里

(4) build 工程,左边的状态栏 Products 目录下 libxxx.a 文件

     libxxx.a 文件拖到终端查看此文件目录,cd 此目录open . 打开目录,拷贝 libxxx.a 文件

(5) 选中工程 Build Phases 将libxxx.a 添加到工程库里


2.建立测试工程

(0) xocde new project选择

(1) OS X..Application..Command Line Tool

(2) Language: C++

(3) 将 lua-5.2.3/src 里的文件拷贝到, main.cpp 目录下(libxxx.a 找不到头文件,实际上只用到 xxx.h文件)

     真正用到的还是 libxxx.a 库。


二、lua C 交互

lua 和 C 交互通过抽象栈(先出后进,实际上一个指针控制 lua_State *L),栈顶到底(-1, -2, -3 ...),栈底到顶(1, 2, 3 ...)

函数:

lua_setglobal:lua 每次取此变量值都直接从lua解释器里取值,不需要通过解释器在访问 C 代码了(效率提升了)

  lua_pushstring(L, "123")

  lua_setglobal(L, "变量名")

  lua: print(变量名) 输出 123

lua_settable:同 lua_setglobal 一样

  lua_pushstring(L,"MOUSE_X")

  lua_pushnumber(L, 2)

  lua_settable(L, idx)

  lua_gettable(L, idx)   通过索引 idx 取 table 里的值

luaL_ref:返回栈中某个位置的索引,下次直接通过 lua_getref(L, index) 就能找到此值,相当于 key-value

  int index =luaL_ref(L,-1)

  lua_getref(L, index)           返回栈 -1 位置的值

  luaL_unref(L, indxe)          记得释放

lua_gettop(L):栈元素个数

lua_settop(L, num):设置栈元素个数,num==0 栈清空

栈操作:

lua_pushvalue把栈中指定索引的元素复制一份到栈顶

lua_remove删除指定索引的元素

lua_insert:移动栈顶元素到指定索引的位置,栈中数目没有改变
lua_replace:从栈顶弹出元素值并将其设置到指定索引位置,栈中的数目减一
lua_checkstack:确保堆栈上至少有 extra 个空位。如果不能把堆栈扩展到相应的尺寸,函数返回 false 。这个函数永远不会缩小堆栈。
lua_pop:从栈顶弹出n个元素,它是一个lua_settop的包装:#define lua_pop(L,n)  lua_settop(L, -(n)-1)

api参考http://blog.csdn.net/zhangjingyangguang/article/details/5221691

1.加载 lua 文件

1.创建声明 lua

2. 打开 lua 库(否则 lua文件里 print 找不到)

3. 加载 lua 文件

4. 执行 lua 文件(加载 lua 里声明的全局变量或方法)

5. c 调用 lua (重点) 后面讲

6.关闭 lua 声明

#include <iostream>
extern "C"
{
    #include "lua.h"
    #include "lauxlib.h"
    #include "lualib.h"
}

void bail(lua_State *L, char *msg)
{
    fprintf(stderr, "\nFATAL ERROR:\n  %s: %s\n\n",
            msg, lua_tostring(L, -1));
}

int main(int argc, const char * argv[])
{
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);
    
    if (luaL_loadfile(L, ".../LuaC/luaOne.lua"))
        bail(L, "luaL_loadfile() failed");
    
    if (lua_pcall(L, 0, 0, 0))
        bail(L, "lua_pcall() failed");
    
    /*
     C 调用 lua 方法
     */
    
    lua_close(L);
    
    return 0;
}

2.调用 lua 方法

(1)获得 lua 的全局方法自动入栈

(2)传递的参数入栈

(3)执行调用 lua 的全局方法..之后..自动全部出栈

(4)lua 取出参数进行处理,返回参数给 C 自动入栈(此时栈已经空了)

(5)C 取出入栈的参数

(6)参数出栈需要手动


lua_pcall(L, 传lua参数个数, lua返回参数个数(一般1), 一般是0)

    lua_getglobal(L, "square");
    lua_pushnumber(L, 6);
    lua_pcall(L, 1, 1, 0);                  //最好错误处理
    int mynumber = lua_tonumber(L, -1);
    lua_pop(L, 1);

3.参数和返回值 table 类型

(1)创建 table 自动放入栈顶

(2)push 一个key

(3)push一个value(栈元素位置value:-1、key:-2、table:-3)

(4)把 push 的 key 和 value 放到创建的 table 里,key value 自动出栈(此时栈里只有新建的 table)

(5)重复执行 (2) (3) (4)

(6)调用 lua 方法

    lua_getglobal(L, "tweaktable");
    
    lua_newtable(L);
    
    lua_pushliteral(L, "fname");
    lua_pushliteral(L, "Margie");
    lua_settable(L, -3);
    lua_pushliteral(L, "lname");
    lua_pushliteral(L, "Martinez");
    lua_settable(L, -3);
    
    lua_pcall(L, 1, 1, 0);

(1)lua 返回的 table 自动入栈

(2)push 一个 nil 进栈(栈元素位置:nil:-1、返回的table:-2)

(3)判断 table 是否有元素,有:栈顶出栈(及-1位置出栈),key 入栈 value 入栈

    栈元素位置(value:-1、key:-2、table:-3)  入栈出栈都是自动的

(4)取栈顶 value,value 出栈(手动),之后在取 key

(5)栈元素位置(key:-1、table:-2)

(6)回到 (3) 的操作 key 代替了之前的 nil

    lua_pushnil(L);
    const char *k, *v;
    while (lua_next(L, -2))
    {
        v = lua_tostring(L, -1);
        lua_pop(L,1);
        k = lua_tostring(L, -1);
    }

变量 table 里的table

void decode(lua_State *L)
{
    const char *k, *v;
    lua_pushnil(L);
    
    while (lua_next(L, -2))
    {
        v = lua_tostring(L, -1);
        if (lua_istable(L, -1))
        {
            decode(L);
            lua_pop(L,1);
            continue;
        }
        
        lua_pop(L,1);
        k = lua_tostring(L, -1);
    }
}

error: 出错时 error 被压到栈定,通过 lua_tostring(L, -1) 输出,之后 lua_pop(L, 1)出栈

注意: 一些 api 用法可以直接看源码,注意可能出错得地方

性能:

参考:http://blog.codingnow.com/2006/01/_lua.html

一般调用过程,lua 调用解释器在通过解释器调用 C 做得操作,返回结果在通过解释器给lua (实际上都是在栈里操作)

1.有些经常用到的数据只调用一次 C 把结果放到解释器栈里,以后每次从解释器栈里取此数据

2.lua_pushstring 每次都要在栈里比较看是否有相同拷贝,没有创建新的拷贝。

  经常用到的 string 设置一个索引,每次用这个索引直接从栈里取,省去了拷贝过程

3.每次都是 lua .. 解释器 .. C 程序,返回 C 程序 .. 解释器 .. lua

  加载 lua 文件时返回一个方法给 C,C 可以直接在此方法里赋值省去了再次调用lua。

4.cocos2dx setPosition 专递的是 x y 两个 number 数字不是table,

  这样能够提升性能官方说事 10 倍,setPosition 用得很频繁



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值