• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell
您的位置:首页 > 脚本语言 >Lua > Lua教程(六):绑定一个简单的C++类

Lua教程(六):绑定一个简单的C++类

作者:junjie 字体:[增加 减小] 来源:互联网

junjie 通过本文主要向大家介绍了Lua教程(五):C/C++操作Lua数组和字符串示例等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

本文是最后一篇C/C++与Lua交互的教程,在此之后,我们会结合Cocos2D-X来介绍Lua绑定。本文主要介绍如何绑定一个简单的C++类到Lua里面,并且提供Lua的面向对象访问方式。

绑定C++类

定义C++类

首先,我们定义一个Student类,它拥有名字(字符串类型)和年龄(整型),并且提供一些getter和setter,最后还提供了一个print方法.这里有Student类的定义和实现:Student.h和Student.cpp

编写绑定代码

首先,让我们编写在Lua里面创建Student对象的方法:
Student **s =  (Student**)lua_newuserdata(L, sizeof(Student*));  // lua will manage Student** pointer
*s = new Student;  //这里我们分配了内存,后面我们会介绍怎么让Lua在gc的时候释放这块内存
</div>

接下来是getName,setName,setAge,getAge和print方法的定义:

int l_setName(lua_State* L)
{
    Student **s = (Student**)lua_touserdata(L, 1);
    luaL_argcheck(L, s != NULL, 1, "invalid user data");

    luaL_checktype(L, -1, LUA_TSTRING);

    std::string name = lua_tostring(L, -1);
    (*s)->setName(name);
    return 0;
}

int l_setAge(lua_State* L)
{
    Student **s = (Student**)lua_touserdata(L,1);
    luaL_argcheck(L, s != NULL, 1, "invalid user data");
    luaL_checktype(L, -1, LUA_TNUMBER);
    int age = lua_tonumber(L, -1);
    (*s)->setAge(age);
    return 0;
}

int l_getName(lua_State* L)
{
    Student **s = (Student**)lua_touserdata(L,1);
    luaL_argcheck(L, s != NULL, 1, "invalid user data");
    lua_settop(L, 0);
    lua_pushstring(L, (*s)->getName().c_str());
    return 1;
}

int l_getAge(lua_State* L)
{
    Student **s = (Student**)lua_touserdata(L,1);
    luaL_argcheck(L, s != NULL, 1, "invalid user data");
    lua_settop(L, 0);
    lua_pushnumber(L, (*s)->getAge());
    return 1;
}

int l_print(lua_State* L)
{
    Student **s = (Student**)lua_touserdata(L,1);
    luaL_argcheck(L, s != NULL, 1, "invalid user data");
    (*s)->print();

    return 0;
}
</div>

从这里我们可以看到,userdata充当了C++类和Lua的一个桥梁,另外,我们在从Lua栈里面取出数据的时候,一定要记得检查数据类型是否合法。

注册C API到Lua里面

最后,我们需要把刚刚编写的这些函数注册到Lua虚拟机里面去。
static const struct luaL_Reg stuentlib_f [] = {
    {"create", newStudent},
    {"setName",l_setName},
    {"setAge", l_setAge},
    {"print", l_print},
    {"getName",l_getName},
    {"getAge", l_getAge},
    {NULL, NULL}
};
int luaopen_student (lua_State *L) {
    luaL_newlib(L, stuentlib_f);
    return 1;
}
</div>
现在,我们把luaopen_student函数添加到之前的注册函数里面去:
static const luaL_Reg lualibs[] =
{
    {"base", luaopen_base},
    {"io", luaopen_io},
    {"cc",luaopen_student},
    {NULL, NULL}
};
const luaL_Reg *lib = lualibs;
for(; lib->func != NULL; lib++)
{
    //注意这里如果使用的不是requiref,则需要手动在Lua里面调用require "模块名"
    luaL_requiref(L, lib->name, lib->func, 1);
    lua_settop(L, 0);
}</div>

Lua访问C++类

现在,我们在Lua里面操作这个Student类。注意,我们绑定的每一个函数都需要一个student对象作为参数,这样使用有一点不太方便。
local s = cc.create()
cc.setName(s,"zilongshanren")
print(cc.getName(s))
cc.setAge(s,20)
print(cc.getAge(s))
cc.print(s)
</div>
最后,输出的结果为:
zilongshanren
20
My name is: zilongshanren, and my age is 20
</div>

提供Lua面向对象操作API

现在我们已经可以在Lua里面创建C++类的对象了,但是,我们最好是希望可以用Lua里面的面向对象的方式来访问。

local s = cc.create()
s:setName("zilongshanren")
s:setAge(20)
s:print()</div>
而我们知道s:setName(xx)就等价于s.setName(s,xx),此时我们只需要给s提供一个metatable,并且给这个metatable设置一个key为”__index”,value等于它本身的metatable。最后,只需要把之前Student类的一些方法添加到这个metatable里面就可以了。

MetaTable

我们可以在Registry里面创建这个metatable,然后给它取个名字做为索引,注意,为了避免名字冲突,所以这个名字一定要是独一无二的。
//创建名字为tname的metatable并放在当前栈顶,同时把它与Registry的一个key为tname的项关联到一起
   int   luaL_newmetatable (lua_State *L, const char *tname);
   //从当前栈顶获取名字为tname的metatable
   void  luaL_getmetatable (lua_State *L, const char *tname);
   //把当前栈index处的userdata取出来,同时检查此userdata是否包含名字为tname的metatable
   void *luaL_checkudata   (lua_State *L, int index,const char *tname);
</div>
接下来,我们要利用这3个C API来为我们的student userdata关联一个metatable.

修改绑定代码

首先,我们需要创建一个新的metata

您可能想查找下面的文章:

相关文章

  • Lua中的迭代器和泛型for实例
  • lua中使用packagepath解决多个项目的路径冲突问题
  • Lua中写排序算法实例(选择排序算法)
  • 把Lua编译进nginx步骤方法
  • Lua性能优化技巧(二):基本事实
  • lua中使用毫秒精度时间的方法
  • Lua中的闭合函数、非全局函数与函数的尾调用详解
  • Lua中调用函数使用点号和冒号的区别
  • Lua中的捕获机制和转换技巧介绍
  • Lua中string.lower()使用指南

文章分类

  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell

最近更新的内容

    • Redis教程(五):Set数据类型
    • Lua中的元表和元方法学习笔记
    • Lua面向对象之类和继承浅析
    • Lua中计算、执行字符串中Lua代码的方法
    • Lua中实现递归删除一个文件夹
    • Lua之协同程序coroutine代码实例
    • Lua中获取table长度的方法
    • Lua中的协同程序详解
    • Lua中的持久化和序列化详解
    • Lua中的一些常用函数库实例讲解

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有