http://dualface.github.io/blog/2013/01/27/call-objectivec-from-lua/

月初的时候,发了一篇关于 Lua 与 Java 互操作的文章,里面提到了我创建的 LuaJavaBridge 工具。现在,最新的 Lua 与 Objective-C 互操作工具也出来了。因为是专门针对 cocos2d-x 的,所以命名为 CCLuaObjcBridge。

PS: 以前的 LuaJavaBridge 也会改名为 CCLuaJavaBridge,并且参考现在 CCLuaObjcBridge 的实现,做了不少改进,完成后也会发布。

CCLuaObjcBridge(后文简称 luaoc)的功能就是从 Lua 里直接掉用“任意 Objective-C 类方法”。利用这个特性,封装各种 iOS 上的库简直碉堡了,堪称 cocos2d-x Lua 游戏开发的神器 ^_^

luaoc 的主要特征

  • 可以从 Lua 调用 Objective-C Class Method
  • 调用 Objective-C 方法时,支持 int/float/boolean/String/Lua function/Lua table 六种参数类型
  • 可以将 Lua function 作为参数传递给 Objective-C,并让 Objective-C 保存 Lua function 的引用
  • 可以从 Objective-C 调用 Lua 的全局函数,或者调用引用指向的 Lua function

主要功能和 luaj 是一样的,但相比老版本 luaj 做了一些针对 Objective-C 的调整。

luaoc 用法示例

下面的代码演示了如何调用 91 SDK:

Lua 代码:

-- 注册回调函数,在玩家离开 91 平台界面时显示一个消息
-- PS: 91 SDK 的支付接口不会直接返回状态给客户端,支付需要在服务端验证
local function callback(event)
if event == "SDKNDCOM_LEAVE_PLATFORM" then
print("充值正在进行中,稍候您就能收到金币啦")
end
end luaoc.callStaticMethod("SDKNdCom", "registerScriptHandler", {listener = callback}) -- 进入 91 的支付接口
local args = {
orderId = "order-00001001001",
coins = 1000,
}
local ok, ret = luaoc.callStaticMethod("SDKNdCom", "payForCoins", args)
if not ok then
print(string.format("SDKNdCom.payForCoins() - call API failure, error code: %s", tostring(ret)))
end

下面代码是 Objective-C 写的中间层,用来沟通 91 SDK 和 Lua 代码。

Objective-C 代码:

+ (NSDictionary *) payForCoins:(NSDictionary *)dict
{
NSString *orderId = [dict objectForKey:@"orderId"];
if (!orderId || [orderId length] == 0)
{
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
orderId = [(NSString *)string autorelease];
} int coins = 0;
if ([dict objectForKey:@"coins"])
{
coins = [[dict objectForKey:@"coins"] intValue];
} NSString *description = [dict objectForKey:@"description"];
if (!description)
{
description = @"";
} int ret = [[NdComPlatform defaultPlatform] NdUniPayForCoin:orderId
needPayCoins:coins
payDescription:description]; return [NSDictionary dictionaryWithObjectsAndKeys:orderId, @"orderId",
[NSNumber numberWithInt:ret], @"error", nil];
}

由于无法直接获取 Objective-C 方法的参数个数和类型,所以如果要从 Objective-C 方法里接收 Lua 传递的参数,那么只能以 NSDictionary 的形式。

上述代码中,Lua 端传递了一个包含 orderId 和 coins 的表格作为参数。这个表格会被 luaoc 自动转换为 NSDictionary 对象,并传入 payForCoins:(NSDictionary*) 方法。

不过从 Objective-C 返回值给 Lua 时,就可以返回各种类型的值。目前支持的值类型有 int/float/BOOL/NSString/NSDictionary。特别是可以返回 NSDictionary 类型后,Lua 代码从 Objective-C 端获取数据就简单很多了。

从 Objective-C 调用 Lua

由于 CCLuaObjcBridge 已经集成到quick-cocos2d-x(一个基于 cocos2d-x 的 Lua 游戏引擎)中,所以从 Objective-C 调用 Lua 也更简单灵活:

// functionId 是 Lua function 的引用 ID,参考 LuaJavaBridge 文章中的描述

// 1. 将引用 ID 对应的 Lua function 放入 Lua stack
CCLuaObjcBridge::pushLuaFunctionById(functionId); // 2. 将需要传递给 Lua function 的参数放入 Lua stack
CCLuaValueDict item;
item["title"] = CCLuaValue::stringValue("hello");
item["coins"] = CCLuaValue::intValue(1000);
item["success"] = CCLuaValue::booleanValue(TRUE);
CCLuaObjcBridge::getStack()->pushCCLuaValueDict(item); // 3. 执行 Lua function
CCLuaObjcBridge::getStack()->executeFunction(1); // 4. 释放引用 ID
CCLuaObjcBridge::releaseLuaFunctionById(callbackId);

CCLuaObjcBridge::getStack() 会返回一个 CCLuaStack 对象的指针。
CCLuaStack 是 quick-cocos2d-x 引入的新对象,封装了 Lua stack 的一些常用操作。例如要将值放入 Lua stack 就提供了下列方法,支持各种数据类型:
void pushInt(int intValue);
void pushFloat(float floatValue);
void pushBoolean(bool boolValue);
void pushString(const char* stringValue);
void pushString(const char* stringValue, int length);
void pushNil(void);
void pushCCObject(CCObject* objectValue, const char* typeName);
void pushCCLuaValue(const CCLuaValue& value);
void pushCCLuaValueDict(const CCLuaValueDict& dict);
void pushCCLuaValueArray(const CCLuaValueArray& array);
相比 LuaJavaBridge,CCLuaObjcBridge 更容易使用、传递数据也更方便。以后 LuaJavaBridge 也会更名为 CCLuaJavaBridge,并使用相同的值传递机制。

CCLuaObjcBridge - Lua 与 Objective-C 互操作的简单解决方案的更多相关文章

  1. LuaJavaBridge - Lua 与 Java 互操作的简单解决方案

    http://dualface.github.io/blog/2013/01/01/call-java-from-lua/ 最近在游戏里要集成中国移动的 SDK,而这些 SDK 都是用 Java 编写 ...

  2. LuaJavaBridge - lua与java互操作的简单解决方案

    引入:Android平台代码和Lua代码的交互均通过C++和Java交互,Lua再和C++交互(lua  <==> C++ <==> java) 我最开始遇见这种lua调用ja ...

  3. vue-router同路由$router.push不跳转一个简单解决方案

    vue-router同路由$router.push不跳转一个简单解决方案 vue-router跳转一般是这么写: toCurrentPage: function(thisId){ this.$rout ...

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

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

  5. 团队交流合作简单解决方案:TeamViewer远程控制&会议演示 + HyperCam屏幕录制(免费)

    一. 教程摘要 做开发,团队合作是少不了的.而在合作中,有一部分是花在交流讨论上,其中包括初期的任务分配,成员的进度汇报,以及资源和心得分享等.该教程介绍了两个免费的软件,搭配起来,适合人数不超过25 ...

  6. 高并发简单解决方案————redis队列缓存+mysql 批量入库(ThinkPhP)

    问题分析 问题一:要求日志最好入库:但是,直接入库mysql确实扛不住,批量入库没有问题,done.[批量入库和直接入库性能差异] 问题二:批量入库就需要有高并发的消息队列,决定采用redis lis ...

  7. 转载:【高并发简单解决方案 | 靠谱崔小拽 】redis队列缓存 + mysql 批量入库 + php离线整合

    需求背景:有个调用统计日志存储和统计需求,要求存储到mysql中:存储数据高峰能达到日均千万,瓶颈在于直接入库并发太高,可能会把mysql干垮. 问题分析 思考:应用网站架构的衍化过程中,应用最新的框 ...

  8. 基于Annotation与SpringAOP的缓存简单解决方案

    前言: 由于项目的原因,需要对项目中大量访问多修改少的数据进行缓存并管理,为达到开发过程中通过Annotation简单的配置既可以完成对缓存的设置与更新的需求,故而设计的该简易的解决方案. 涉及技术: ...

  9. [项目回顾]基于Annotation与SpringAOP的缓存简单解决方案

    前言: 由于项目的原因,需要对项目中大量访问多修改少的数据进行缓存并管理,为达到开发过程中通过Annotation简单的配置既可以完成对缓存的设置与更新的需求,故而设计的该简易的解决方案. 涉及技术: ...

随机推荐

  1. 中秋H5,这篇脑洞开的可以!

    案例:嫦娥--寻开心出品:凯迪仕 1.内容:这是一支视频类H5案例.Loading完毕进入页面,首屏提示案例最佳观看方式为先锁屏再横屏.点击开始按钮播放视频,视频讲述"葫芦娃"缠着 ...

  2. Extjs6(五)——写一个包含toolbar、form、grid的子页面

    本文基于ext-6.0.0 这个页面布局是很多管理系统的常用布局,具体如下图: 一.页面主体personalInfo.js 整个页面采用border布局,分成三部分,这个personalInfo.js ...

  3. 张高兴的 Windows 10 IoT 开发笔记:使用 MAX7219 驱动 8×8 点阵

    GitHub:https://github.com/ZhangGaoxing/windows-iot-demo/tree/master/MAX7219

  4. mongdb单节点安装方法

    mongo单节点环境安装(linux) 安装包 下载地址: (https://www.mongodb.com/download-center) 用户权限/目录 创建 dbuser用户 groupadd ...

  5. 最新版multer1.3.0上传文件

    完整项目资源下载路径:http://download.csdn.net/detail/qq_28506819/9851744 使用方法: cd到跟目录,然后npm install. 运行项目,npm ...

  6. C++STL之双端队列容器

    C++STL之双端队列容器 deque双端队列容器与vector很类似,采用线性表顺序存储结构.但与vector区别,deque采用分块的线性存储结构来存储数据,每块的大小一般为512B,将之称为de ...

  7. Codeforces Round #386 (Div. 2) C. Tram

    C. Tram time limit per test 1 second memory limit per test 256 megabytes input standard input output ...

  8. 颜色框架Hue相关使用方法

    Hue地址 cocoapods安装Hue pod "Hue" 导入框架 import Hue 将十六进制数字变成对应的颜色值 let color = UIColor.init(he ...

  9. MVC架构下,使用NPOI读取.DOCX文档中表格的内容

    1.使用NPOI,可以在没有安装office的设备上读wiod.office.2.本文只能读取.docx后缀的文档.3.MVC架构中,上传文件只能使用form表单提交,转到控制器后要依次实现文件上传. ...

  10. linux-touch

    linux-touch 用于创建文件或者更新文件的修改日期 命令参数 - d yyyymmdd:把文件的存取或修改时间改为  yyyy年mm月dd日 - a :只把文件的存取时间改成当前时间 - m: ...