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 代码:

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

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

Objective-C 代码:

  1. + (NSDictionary *) payForCoins:(NSDictionary *)dict
  2. {
  3. NSString *orderId = [dict objectForKey:@"orderId"];
  4. if (!orderId || [orderId length] == 0)
  5. {
  6. CFUUIDRef theUUID = CFUUIDCreate(NULL);
  7. CFStringRef string = CFUUIDCreateString(NULL, theUUID);
  8. CFRelease(theUUID);
  9. orderId = [(NSString *)string autorelease];
  10. }
  11. int coins = 0;
  12. if ([dict objectForKey:@"coins"])
  13. {
  14. coins = [[dict objectForKey:@"coins"] intValue];
  15. }
  16. NSString *description = [dict objectForKey:@"description"];
  17. if (!description)
  18. {
  19. description = @"";
  20. }
  21. int ret = [[NdComPlatform defaultPlatform] NdUniPayForCoin:orderId
  22. needPayCoins:coins
  23. payDescription:description];
  24. return [NSDictionary dictionaryWithObjectsAndKeys:orderId, @"orderId",
  25. [NSNumber numberWithInt:ret], @"error", nil];
  26. }

由于无法直接获取 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 也更简单灵活:

  1. // functionId 是 Lua function 的引用 ID,参考 LuaJavaBridge 文章中的描述
  2. // 1. 将引用 ID 对应的 Lua function 放入 Lua stack
  3. CCLuaObjcBridge::pushLuaFunctionById(functionId);
  4. // 2. 将需要传递给 Lua function 的参数放入 Lua stack
  5. CCLuaValueDict item;
  6. item["title"] = CCLuaValue::stringValue("hello");
  7. item["coins"] = CCLuaValue::intValue(1000);
  8. item["success"] = CCLuaValue::booleanValue(TRUE);
  9. CCLuaObjcBridge::getStack()->pushCCLuaValueDict(item);
  10. // 3. 执行 Lua function
  11. CCLuaObjcBridge::getStack()->executeFunction(1);
  12. // 4. 释放引用 ID
  13. CCLuaObjcBridge::releaseLuaFunctionById(callbackId);

    CCLuaObjcBridge::getStack() 会返回一个 CCLuaStack 对象的指针。
    CCLuaStack quick-cocos2d-x 引入的新对象,封装了 Lua stack 的一些常用操作。例如要将值放入 Lua stack 就提供了下列方法,支持各种数据类型:
  1. void pushInt(int intValue);
  2. void pushFloat(float floatValue);
  3. void pushBoolean(bool boolValue);
  4. void pushString(const char* stringValue);
  5. void pushString(const char* stringValue, int length);
  6. void pushNil(void);
  7. void pushCCObject(CCObject* objectValue, const char* typeName);
  8. void pushCCLuaValue(const CCLuaValue& value);
  9. void pushCCLuaValueDict(const CCLuaValueDict& dict);
  10. void pushCCLuaValueArray(const CCLuaValueArray& array);
    相比 LuaJavaBridgeCCLuaObjcBridge 更容易使用、传递数据也更方便。以后 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. 反射型 DDoS 攻击的原理和防范措施

    随着僵尸网络的兴起,同时由于攻击方法简单.影响较大.难以追查等特点,分布式拒绝服务攻击(DDoS,Distributed Denial of Service)得到快速壮大和日益泛滥. 成千上万主机组成 ...

  2. win10 UWP Markdown 含源代码

    Windows下没有比较好的Markdown编辑器 我就自己写一个 csdn的Markdown很好,就是我需要截图保存有麻烦 需要把我的截图保存在本地,然后上传 这个过程比较麻烦 csdn的图没法外链 ...

  3. 【转】嵌入式C语言调试开关

    在调试程序时,经常会用到assert和printf之类的函数,我最近做的这个工程里就有几百个assert,在你自认为程序已经没有bug的时候,就要除去这些调试代码,应为系统在正常运行时这些用于调试的信 ...

  4. javascript入门知识点总结(一)

    学了几天javascript,现总结一下原生javascript的基本知识点. 一.javascript基本知识 变量 定义: var a = 123; var b = 'abc'; //连写 var ...

  5. Python Nose框架编写测试用例方法

    1. 关于Nose nose项目是于2005年发布的,也就是 py.test改名后的一年.它是由 Jason Pellerin 编写的,支持与 py.test 相同的测试习惯做法,但是这个包更容易安装 ...

  6. Cocos 2d-X Lua 游戏添加苹果内购(二) OC和Lua交互代码详解

    这是第二篇 Cocos 2d-X Lua 游戏添加苹果内购(一) 图文详解准备流程 这是前面的第一篇,详细的说明了怎样添加内购项目以及填写银行信息提交以及沙盒测试员的添加使用以及需要我们注意的东西,结 ...

  7. mysql 中翻页

    万变不离其中 select * from tableName where 条件 limit 当前页码*页面容量-1 , 页面容量

  8. C++输入输出cin与cout

    输入对象 istream:cin(标准输入) 输出对象 ostream: cout(标准输出), cerr(标准错误),clog(输出程序运行时的一般性信息)

  9. 编程&blog处女篇-用C#求100以内的质数

    using System;namespace Loops{ class Program { static void Main(string[] args) { /*局部变量定义*/ int i, j; ...

  10. 微信小程序左滑删除功能

    效果图如下: wxml代码: <view class="container"> <view class="touch-item {{item.isTou ...