Lua和C++交互
Lua 可以作为程序库用来扩展应用的功能,也就是 Lua 可以作为扩展性语言的原因所在。同时,Lua 程序中可以注册有其他语言实现的函数,这些函数可能由 C 语言(或其他语言)实现,可以增加一些不容易由 Lua 实现的功能。这使得 Lua 是可扩展的。与上面两种观点(Lua 作为扩展性语言和可扩展的语言)对应的 C 和 Lua 中间有两种交互方式。
第一种,C 作为应用程序语言,Lua 作为一个库使用;
第二种,反过来,Lua 作为程序语言,C 作为库使用。这两种方式,C 语言都使用相同的 API 与 Lua 通信,因此 C 和Lua 交互这部分称为 C API。
C API 是一个 C 代码与 Lua 进行交互的函数集。他有以下部分组成:读写 Lua 全局变量的函数,获取和调用 Lua 函数的函数,运行 Lua 代码片断的函数,注册 C 函数然后可以在Lua 中调用被注册的函数,等等。
-
static int averageFunc(lua_State *L)
-
{
-
int n = lua_gettop(L);//获取栈顶元素,表示参数数量
-
double sum = 0;
-
int i;
-
/* 循环求参数之和 */
-
for (i = 1; i <= n; i )
-
sum = lua_tonumber(L, i);
-
lua_pushnumber(L, sum / n); //压入平均值
-
lua_pushnumber(L, sum); //压入和
-
return 2; //返回两个结果
-
}
-
static int sayHelloFunc(lua_State* L)
-
{
-
printf("hello world!");
-
return 0;
-
}
-
static const struct luaL_Reg myLib[] =
-
{
-
{"average", averageFunc},
-
{"sayHello", sayHelloFunc},
-
{NULL, NULL} //数组中最后一对必须是{NULL, NULL},用来表示结束
-
}
-
int luaopen_mLualib(lua_State *L)
-
{
-
luaL_register(L, "ss", myLib);
-
return 1; // 把myLib表压入了栈中,所以就需要返回1
-
}
例子讲解:
local spr = cc.Sprite:create()
cc是一张表(table),表(table)是lua里面唯一的数据结构,cc存于_G中,_G是lua里面的全局表,cc表中存了所有cocos绑定的常量和“类”。
Sprite也是个表(table),Sprite表是怎样跟c 代码关联起来的呢,这就要分析c 的绑定代码了。首先来看看Sprite表里面的内容
-
["Sprite"] = {--table: 0x0032cce0
-
[".isclass"] = "true",
-
[".metatable"] = table: 0x0032c690
-
},
通过打印发现,Sprite表里面就一条数据key=[".isclass"] value=true,这个表明这个此table是cocos绑定的一个类型。看来秘密都在元表(metatable)里面。元表(metatable)在注册表(LUA_REGISTRYINDEX)里面,关于lua的全局表(_G)、注册表(Register)、元表(metatable),这里不再介绍了,不理解的需要先去学习一下。下面来打印一下Sprite的元表(metatable)里面的内容
-
["cc.Sprite"] = {--table: 0x0032c690
-
["getTextureRect"] = "function: 0x00b9b430",
-
["getBatchNode"] = "function: 0x00b9afe8",
-
["setTextureAtlas"] = "function: 0x00b9b770",
-
["new"] = "function: 0x00b9b168",
-
["setDisplayFrameWithAnimationName"] = "function: 0x00b9b750",
-
["create"] = "function: 0x003284a8",
-
["__lt"] = "function: 0x0032cbf0",
-
["getTexture"] = "function: 0x00b9b2b8",
-
["__sub"] = "function: 0x0032cc58",
-
["initWithFile"] = "function: 0x00b9b450",
-
["isTextureRectRotated"] = "function: 0x00b9b3e8",
-
["removeAllChildrenWithCleanup"] = "function: 0x00b9b050",
-
["setTextureRect"] = "function: 0x00b9b098",
-
["setDirty"] = "function: 0x00b9b398",
-
["getSpriteFrame"] = "function: 0x00b9b790",
-
["__newindex"] = "function: 0x0032c710",
-
["__eq"] = "function: 0x0032cc30",
-
["setPolygonInfo"] = "function: 0x00328488",
-
["initWithPolygon"] = "function: 0x00328440",
-
["__le"] = "function: 0x0032cc10",
-
["setFlippedX"] = "function: 0x00b9af60",
-
["createWithSpriteFrame"] = "function: 0x00b9be50",
-
["createWithSpriteFrameName"] = "function: 0x00b9be00",
-
["tolua_ubox"] = "table: 0x002c86f0" , -- loop table,
-
["createWithTexture"] = "function: 0x00b9b5c0",
-
["setTexture"] = "function: 0x00b9b298",
-
["setVertexRect"] = "function: 0x00b9b5a0",
-
["isFlippedY"] = "function: 0x00b9b558",
-
["isFlippedX"] = "function: 0x00b9b518",
-
["getResourceType"] = "function: 0x00b9afa8",
-
["setFlippedY"] = "function: 0x00b9b2f8",
-
["setBlendFunc"] = "function: 0x003283f8",
-
["__div"] = "function: 0x0032c6b8",
-
["getTextureAtlas"] = "function: 0x00b9b490",
-
["__index"] = "function: 0x0032c6f0",
-
["setAtlasIndex"] = "function: 0x00b9b358",
-
["getAtlasIndex"] = "function: 0x00b9b6b8",
-
["isDirty"] = "function: 0x00b9b338",
-
["getResourceName"] = "function: 0x00b9b7d8",
-
["getOffsetPosition"] = "function: 0x00b9b030",
-
["setBatchNode"] = "function: 0x00b9b6d8",
-
["__gc"] = "function: 0x002c1a90",
-
["__call"] = "function: 0x0032cc98",
-
["__mul"] = "function: 0x0032cc78",
-
["initWithSpriteFrame"] = "function: 0x00b9b4d8",
-
["__add"] = "function: 0x0032c730",
-
["initWithTexture"] = "function: 0x00b9afc8",
-
["setSpriteFrame"] = "function: 0x00b9b1b0",
-
["initWithSpriteFrameName"] = "function: 0x00b9b650",
-
["isFrameDisplayed"] = "function: 0x00b9b698",
-
["getBlendFunc"] = "function: 0x00b9b6f8",
-
[".metatable"] = table: 0x002ca9c8
-
}
cc.Sprite:create,在元表(metatable)的前半部分找到到了create方法,下面来看一看create方法里面的内容:
-
int lua_cocos2dx_Sprite_create(lua_State* tolua_S)
-
{
-
int argc = 0;
-
bool ok = true;
-
//lua_gettop获取栈顶正索引,也表示栈内的元素个数
-
argc = lua_gettop(tolua_S)-1;//获取栈顶下面的正索引
-
do{
-
if (argc == 1){//表示栈内有两个元素
-
std::string arg0;
-
ok &= luaval_to_std_string(tolua_S, 2,&arg0, "cc.Sprite:create");
-
if (!ok) { break; }
-
cocos2d::Sprite* ret = cocos2d::Sprite::create(arg0);
-
object_to_luaval<cocos2d::Sprite>(tolua_S, "cc.Sprite",(cocos2d::Sprite*)ret);
-
return 1;
-
}
-
} while (0);
-
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d", "cc.Sprite:create",argc, 2);
-
return 0;
-
}
create方法当然也是一个c函数。lua_gettop()用来获取create函数参数数量,第一个参数是Sprite(table)自己,减1后是真正参数数量,所以create方法必须要用:号调用,元表中其它的方法也一样。函数先用luaval_to_std_string判断传入参数是否是std::string类型,其核心就是调用tolua_isstring函数来进行判定。然后就是调用cocos2d::Sprite::create()创建c 对象,然后调用object_to_luaval<>()函数把c 指针压入lua的栈中,理解这个函数是理解cocos lua的运作流程的关键。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhggicbg
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13