前面2篇分别简单介绍

手动bind C++ 类和lua;http://blog.csdn.net/chenee543216/article/details/12074771

使用tolua++简化工作:http://blog.csdn.net/chenee543216/article/details/12172563

这篇简单聊聊 cocos2dx。

一、基本概念

所谓的lua绑定,其实目的就是导出C++的接口给lua,使得在lua中可以操作C++;

而lua和C/C++的唯一官方接口是stack。so,所谓的binding,就是C++,lua双方通过stack交换信息,然后对stack中信息进行解释,并执行相关动作的过程。

1 、

比如lua想生成一个dog 类,则在lua端: local d = Dog:creat(); 这个只是书面形式,其实lua解释器会自动填充stack。

比如,假设这个时候stack内容变成

"creat"

"Dog"

.........   -- stack bottom

就是说,lua把2个标志入栈,一个是函数名,一个是类名;

在C/C++端,负责绑定的辅助代码(tolua++生成代码+libtolua++,或者我们第一篇文章中的LuaAnimal类)会根据 “Dog"生成一个类,并且根据某个表(见第一篇文章)去调用这个类中于”create“函数对应的函数。

OK,到这里,lua已经调用C、C++完成,并且生成相应的东西。

下面C/C++会把lua需要的返回值再压入stack。

lua端从stack中取出这个值,保留后面使用。

到这里一个完整过程over。

2、

lua端,再次调用 d:sound();

看官大概已经知道了。lua解释器会把相关信息压入stack,我们可以用第一篇中提供的函数stackDump()来展示stack内容。假设如下:

”sound"

"d"

在C++端,取出类实例地址 d,然后根据sound找对应类函数。比如sound00();然后调用d.sound00();

并且将相关返回值入栈,返回给lua。

3、用完以后gc,大家可以给Dog写个 Dog::~Dog()来看gc信息。

具体过程,给~Dog()下个断点,看C/C++ call stack即可。(我自己偷懒了~)

二、cocos2dx

1、

其实lua和cocos2dx木有啥关系,和cocos2dx sdk发生关系的是tolua++ 生成的C++代码而已。

lua是通过这个中间代码去操作cocos2dx的sdk的。

你实现一个功能,可能要写10几个class,还要调用native code,比如OC、或者java层代码。

但是一旦封装好以后,你使用这个功能只要一个简单调用而已。比如在C++端。我们调用 Money *m = Money::create();

我们最多只要用到几个public的函数,或者变量。并不关心private的函数和变量,和具体实现。

这个和tolua++的pkg文件编写规则一致。

再啰嗦一点:


比如上面Money类,我们只要 create,count 。。。 几个函数。那么tolua++生成的中间C++代码也只引用到这几个函数。

class MMM{

public:

int v00001;

int v00002;

....

int V99999;

void f00001();

void f00002()

.....

void f99999();


};

如果,我们在lua中只要调用v0001;和f00001;那么我们的tolua++的pkg只要包括

class MMM{

int v00001;

void f00001;

};

即可,大可不必管其它的东西。

2、cocos2dx自己的lua封装,可以到cocos2dx源码目录下面的tools/tolua++去看。

是官方提炼好的pkg,这些pkg最终都被include到Cocos2d.pkg,然后生成一个LuaCocos2d.cpp (见Makefile文件中描述)

这个LuaCocos2d.cpp就是整个cocos2dx中需要被lua使用的接口函数。

二、动手

我们自己写个练手

其实前面都已经写过了:见第二篇文章。唯一不同的是这里新的代码使用到cocos2dx sdk;

如下:

NativeHelper.h

  1. #ifndef __NativeHelper_H__
  2. #define __NativeHelper_H__
  3.  
  4. #include "cocos2d.h"
  5. USING_NS_CC;
  6. class NativeHelper : public cocos2d::CCLayer
  7. {
  8. public:
  9. virtual bool init();
  10. void openURL(std::string url,bool forceCheck=false);
  11.  
  12. CREATE_FUNC(NativeHelper);
  13. private:
  14.  
  15. };
  16.  
  17. #endif

NativeHelper.cpp

  1. #ifdef ANDROID
  2. #include "NativeHelper.h"
  3. #include <jni.h>
  4. #include "platform/android/jni/JniHelper.h"
  5.  
  6. bool NativeHelper::init()
  7. {
  8.  
  9. return true;
  10. }
  11.  
  12. void NativeHelper::openURL(std::string url,bool forceCheck)
  13. {
  14. JniMethodInfo jmi;
  15. if(JniHelper::getStaticMethodInfo(jmi , "org/cocos2dx/lib/Cocos2dxActivity" , "openUrl" , "([Ljava/lang/String;)V")){
  16. jclass str_cls = jmi.env->FindClass("java/lang/String");
  17.  
  18. jstring str1 = jmi.env->NewStringUTF(url.c_str());
  19. jstring str2 = jmi.env->NewStringUTF("Nothing ...");
  20.  
  21. jobjectArray arrs = jmi.env->NewObjectArray(2 , str_cls , 0);
  22. jmi.env->SetObjectArrayElement(arrs , 0 , str1);
  23. jmi.env->SetObjectArrayElement(arrs , 1 , str2);
  24. jmi.env->CallStaticVoidMethod(jmi.classID , jmi.methodID , arrs);
  25.  
  26. }
  27. }
  28.  
  29. #endif
  1. #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
  2. #include "NativeHelper.h"
  3.  
  4. bool NativeHelper::init()
  5. {
  6.  
  7. return true;
  8. }
  9.  
  10. #define kTextFieldTagOfForumPassword 100
  11.  
  12. //====================================
  13. //typedef void(^AlertBlock)(NSInteger);
  14.  
  15. @interface BlockUIAlertView : UIAlertView
  16. {
  17. NSString *url;
  18. }
  19. //@property(nonatomic,copy)AlertBlock block;
  20. @property(nonatomic,copy)NSString *url;
  21.  
  22. - (id)initWithTitle:(NSString *)title
  23. message:(NSString *)message
  24. cancelButtonTitle:(NSString *)cancelButtonTitle
  25. // clickButton:(AlertBlock)_block
  26. otherButtonTitles:(NSString *)otherButtonTitles;
  27.  
  28. //-(void)setURL:(NSString*)url;
  29.  
  30. @end
  31. @implementation BlockUIAlertView
  32.  
  33. //@synthesize block;
  34. @synthesize url;
  35.  
  36. - (id)initWithTitle:(NSString *)title
  37. message:(NSString *)message
  38. cancelButtonTitle:(NSString *)cancelButtonTitle
  39. // clickButton:(AlertBlock)_block
  40. otherButtonTitles:(NSString *)otherButtonTitles {
  41.  
  42. self = [super initWithTitle:title message:message delegate:self cancelButtonTitle:cancelButtonTitle otherButtonTitles:otherButtonTitles,nil];
  43.  
  44. // if (self) {
  45. // self.block = _block;
  46. // }
  47.  
  48. return self;
  49. }
  50.  
  51. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
  52. // self.block(buttonIndex);
  53.  
  54. if (buttonIndex == 1) {
  55. CCLOG("------------button canceled");
  56. return;
  57. }
  58.  
  59. UITextField *pwdTextField = (UITextField *)[alertView viewWithTag:kTextFieldTagOfForumPassword];
  60. NSString *pwd = [pwdTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
  61. CCLOG("--------------%s",[pwd UTF8String]);
  62.  
  63. if ([pwd caseInsensitiveCompare:@"iamadult"] == NSOrderedSame) {
  64. if ([url length]>[@"http://www.1.com" length]) {
  65. [[UIApplication sharedApplication]openURL:[NSURL URLWithString:url]];
  66. }
  67. }
  68.  
  69. }
  70. @end
  71.  
  72. //====================================
  73. void NativeHelper::openURL(std::string url,bool forceCheck)
  74. {
  75. if (!forceCheck) {
  76. NSString * nsurl = [NSString stringWithCString:url.c_str()
  77. encoding:[NSString defaultCStringEncoding]];
  78.  
  79. [[UIApplication sharedApplication]openURL:[NSURL URLWithString:nsurl]];
  80.  
  81. return;
  82. }
  83.  
  84. BlockUIAlertView *alertView = [[BlockUIAlertView alloc]
  85. initWithTitle:@"请输入字符: iamadult"
  86. message:@"\n\n"
  87. cancelButtonTitle:@"确认"
  88. // clickButton:^(NSInteger indexButton){
  89. // if (indexButton == 0) {
  90. // CCLOG("You press btn 0");
  91. // }else if(indexButton == 1){
  92. // CCLOG("You press btn 1");
  93. // }
  94. // }
  95. otherButtonTitles:@"取消"];
  96.  
  97. [alertView setUrl:[NSString stringWithCString:url.c_str()
  98. encoding:[NSString defaultCStringEncoding]]];
  99.  
  100. UITextField *textFieldPwd = [[UITextField alloc] initWithFrame:CGRectMake(27.0, 60.0, 230.0, 25.0)];
  101. [textFieldPwd setBackgroundColor:[UIColor whiteColor]];
  102. [textFieldPwd setTag:kTextFieldTagOfForumPassword];
  103. [textFieldPwd setPlaceholder:@"请输入密码"];
  104. [alertView addSubview:textFieldPwd];
  105. [textFieldPwd release];
  106.  
  107. [alertView show];
  108. [alertView release];
  109.  
  110. }
  111. #endif

这3个文件实现一个NativeHelper类,这个类只干一件事:调用系统web浏览器打开一个URL。通过宏定义来控制android和ios的独立实现。(ios端和android端的区别是:ios端打开URL之前会弹出一个对话框,让用户输入验证字符。 just for parent protect )

我们调用方式简单如下:

  1. NativeHelper *nhelper = NativeHelper::create();
  2. const std::string strPrivacy = "http://http://blog.csdn.net/chenee543216/article/details/12172563";
  3. nhelper->openURL(strPrivacy,true);

现在,我们把调用需要的2个函数用tolua++导出给lua,there are create() and openURL()

toluaNativeHelper.pkg

  1. 1
  2. 2 $#include "cocos2d.h"
  3. 3 $#include "NativeHelper.h"
  4. 4 class NativeHelper : public cocos2d::CCLayer
  5. 5 {
  6. 6 void openURL(std::string url,bool forceCheck=false);
  7. 7 static NativeHelper* create();
  8. 8 };
  9. 9

生成的命令为: tolua++ -o toluaNativeHelper.cpp toluaNativeHelper.pkg  生成如下cpp文件。

  1. /*
  2. ** Lua binding: toluaNavieHelper
  3. ** Generated automatically by tolua++-1.0.92 on Mon Sep 30 16:21:12 2013.
  4. */
  5.  
  6. #ifndef __cplusplus
  7. #include "stdlib.h"
  8. #endif
  9. #include "string.h"
  10.  
  11. #include "tolua++.h"
  12.  
  13. /* Exported function */
  14. TOLUA_API int tolua_toluaNavieHelper_open (lua_State* tolua_S);
  15.  
  16. #include "cocos2d.h"
  17. #include "NativeHelper.h"
  18.  
  19. /* function to register type */
  20. static void tolua_reg_types (lua_State* tolua_S)
  21. {
  22. tolua_usertype(tolua_S,"NativeHelper");
  23. tolua_usertype(tolua_S,"cocos2d::CCLayer");
  24. }
  25.  
  26. /* method: openURL of class NativeHelper */
  27. #ifndef TOLUA_DISABLE_tolua_toluaNavieHelper_NativeHelper_openURL00
  28. static int tolua_toluaNavieHelper_NativeHelper_openURL00(lua_State* tolua_S)
  29. {
  30. #ifndef TOLUA_RELEASE
  31. tolua_Error tolua_err;
  32. if (
  33. !tolua_isusertype(tolua_S,1,"NativeHelper",0,&tolua_err) ||
  34. !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
  35. !tolua_isboolean(tolua_S,3,1,&tolua_err) ||
  36. !tolua_isnoobj(tolua_S,4,&tolua_err)
  37. )
  38. goto tolua_lerror;
  39. else
  40. #endif
  41. {
  42. NativeHelper* self = (NativeHelper*) tolua_tousertype(tolua_S,1,0);
  43. std::string url = ((std::string) tolua_tocppstring(tolua_S,2,0));
  44. bool forceCheck = ((bool) tolua_toboolean(tolua_S,3,false));
  45. #ifndef TOLUA_RELEASE
  46. if (!self) tolua_error(tolua_S,"invalid 'self' in function 'openURL'", NULL);
  47. #endif
  48. {
  49. self->openURL(url,forceCheck);
  50. }
  51. }
  52. return 0;
  53. #ifndef TOLUA_RELEASE
  54. tolua_lerror:
  55. tolua_error(tolua_S,"#ferror in function 'openURL'.",&tolua_err);
  56. return 0;
  57. #endif
  58. }
  59. #endif //#ifndef TOLUA_DISABLE
  60.  
  61. /* method: create of class NativeHelper */
  62. #ifndef TOLUA_DISABLE_tolua_toluaNavieHelper_NativeHelper_create00
  63. static int tolua_toluaNavieHelper_NativeHelper_create00(lua_State* tolua_S)
  64. {
  65. #ifndef TOLUA_RELEASE
  66. tolua_Error tolua_err;
  67. if (
  68. !tolua_isusertable(tolua_S,1,"NativeHelper",0,&tolua_err) ||
  69. !tolua_isnoobj(tolua_S,2,&tolua_err)
  70. )
  71. goto tolua_lerror;
  72. else
  73. #endif
  74. {
  75. {
  76. NativeHelper* tolua_ret = (NativeHelper*) NativeHelper::create();
  77. tolua_pushusertype(tolua_S,(void*)tolua_ret,"NativeHelper");
  78. }
  79. }
  80. return 1;
  81. #ifndef TOLUA_RELEASE
  82. tolua_lerror:
  83. tolua_error(tolua_S,"#ferror in function 'create'.",&tolua_err);
  84. return 0;
  85. #endif
  86. }
  87. #endif //#ifndef TOLUA_DISABLE
  88.  
  89. /* Open function */
  90. TOLUA_API int tolua_toluaNavieHelper_open (lua_State* tolua_S)
  91. {
  92. tolua_open(tolua_S);
  93. tolua_reg_types(tolua_S);
  94. tolua_module(tolua_S,NULL,0);
  95. tolua_beginmodule(tolua_S,NULL);
  96. tolua_cclass(tolua_S,"NativeHelper","NativeHelper","cocos2d::CCLayer",NULL);
  97. tolua_beginmodule(tolua_S,"NativeHelper");
  98. tolua_function(tolua_S,"openURL",tolua_toluaNavieHelper_NativeHelper_openURL00);
  99. tolua_function(tolua_S,"create",tolua_toluaNavieHelper_NativeHelper_create00);
  100. tolua_endmodule(tolua_S);
  101. tolua_endmodule(tolua_S);
  102. return 1;
  103. }
  104.  
  105. #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
  106. TOLUA_API int luaopen_toluaNavieHelper (lua_State* tolua_S) {
  107. return tolua_toluaNavieHelper_open(tolua_S);
  108. };
  109. #endif

自己添加到cocos2dx工程的class目录即可。

然后在

AppDelegate.cpp 中加入

文件开始部位:

extern int  tolua_toluaNavieHelper_open (lua_State* tolua_S);


调用lua环境初始化之后

CCLuaEngine* pEngine = CCLuaEngine::defaultEngine();

CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);

tolua_toluaNavieHelper_open(pEngine->getLuaStack()->getLuaState());


ok;

现在你只要在lua文件中直接调用NativeHelper相关即可。如下

local nativehelper = NativeHelper:create()

nativehelper:openURL("http://www.sina.com",true)

写那那么多,也不知道说清楚了没有,有问题留言吧。

有错误,也欢迎留言指点。

参考:

http://blog.csdn.net/chenee543216/article/details/12172563

http://blog.csdn.net/chenee543216/article/details/12074771

http://www.himigame.com/lua-game/1259.html

http://blog.csdn.net/musicvs/article/details/8166655

tolua++官网各种文档

lua官网各种文档

cocos2dx lua binding ,cocos2dx 绑定lua测试的更多相关文章

  1. 【cocos2d-x + Lua(1) 绑定Lua并使用tolua++】

    为什么要使用Lua进行游戏开发?转载请注明出处http://www.cnblogs.com/zisou/p/cocos2dx-lua1.html 上面一个问题我觉得在我们使用Lua之前需要深入思考的, ...

  2. 玩转cocos2d-x lua-binding, 实现c++与lua混合编程

    引言 城市精灵GO(http://csjl.teamtop3.com/)是一款基于cocos2d-x开发的LBS社交游戏, 通过真实地图的探索, 发现和抓捕隐匿于身边的野生精灵, 利用游戏中丰富的玩法 ...

  3. 使用BabeLua3.x在cocos2d-x中编辑和调试Lua

    BabeLua是一款基于VS2012/2013的Lua集成开发环境,具有Lua语法高亮,语法检查,自动补全,快速搜索,注入宿主程序内对Lua脚本进行调试,设置断点观察变量值,查看堆栈信息等功能. 如何 ...

  4. 使用BabeLua在cocos2d-x中编辑和调试Lua

    使用BabeLua在cocos2d-x中编辑和调试Lua BabeLua是一款基于VS2012/2013的Lua集成开发环境,具有Lua语法高亮,语法检查.自己主动补全.高速搜索,注入宿主程序内对Lu ...

  5. Cocos2d-x JSB 自己主动绑定bindings

    Javascript Binding (简称JSB) 自己主动绑定教程. Cocos2d-x JSB 自己主动绑定bindings-generator (以下简称B-G) 使用心得 假设想弄清深入原理 ...

  6. Unity3D热更新之LuaFramework篇[07]--怎么让unity对象绑定Lua脚本

    前言 在上一篇文章 Unity3D热更新之LuaFramework篇[06]--Lua中是怎么实现脚本生命周期的 中,我分析了由LuaBehaviour来实现lua脚本生命周期的方法. 但在实际使用中 ...

  7. 【Cocos2d-x JavaScript Binding】

    Cocos2d-x JavaScript Binding结合CocosBuilder跨平台游戏开发简明教程http://www.cocoachina.com/applenews/devnews/201 ...

  8. C++调用Lua编程环境搭建及测试代码示例

    C++调用Lua编程环境搭建及测试代码示例 摘要:测试环境是VS2005+LuaForWindows_v5.1.4-45.exe+WIN7 1.安装lua开发环境LuaForWindows_v5.1. ...

  9. (转) Lua使用心得一 LUA和VC整合

    这几天研究了一下lua,主要关注的是lua和vc之间的整合,把代码都写好放在VC宿主程序里,然后在lua里调用宿主程序的这些代码(或者叫接口.组件,随便你怎么叫),希望能用脚本来控制主程序的行为.这实 ...

随机推荐

  1. Animation动画(一)

    Android的animation由四种类型组成:alpha(渐变透明度动画效果).scale(渐变尺寸伸缩动画效果).translate(画面转换位置移动动画效果).rotate(画面转移旋转动画效 ...

  2. segue生命周期

    segue生命周期:概述: 理解segue工作原理,需要理解一个segue对象的生命周期.segue对象是UIStoryboardSegue的实例或者是它的一个子类.所有iOS app都不能直接创建s ...

  3. Android - Layout时发生'Unfortunately xxx has stopped'

    概述 我在进行LinearLayout和TableLayout的嵌套布局的时候,发生题的错误.如下布局xml代码: <LinearLayout xmlns:android="http: ...

  4. 创建DBLink语句

    --linkName DBLink名 --username 用户名 --password 密码 --tns TNS配置字符串 create database link &linkName co ...

  5. AFN发送请求失败

    发送请求出现这个错误 Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Coc ...

  6. css水平居中的小小探讨

    水平居中是常用的几种布局方式之一.主要分为行内元素的居中,块元素的居中.块元素的居中还分为固定宽度的居中,不定宽度的居中.行内元素的居中,使用text-align:center就可以实现,已知宽度的块 ...

  7. jQuery 如何创建基本插件(翻译)

    有时候,你希望有一块功能在整个代码当中都可以使用.例如,你可能想要有一个单一的方法可以在jQuery选择器上进行调用,用于处理该选择器上的一系列操作.又或许你编写了一个十分有用的工具函数,并希望能够简 ...

  8. [xfire]使用xfire开发webservice的简单示例

    目前项目上有用到xfire,所以临时看了些xfire的资料和示例,自己照着写了一个简单示例. xfire在2007年后已经停止更新,正式更名为apache cxf,也可以说是xfire2.0. xfi ...

  9. Win7 64位 php-5.5.13+Apache 2.4.9+mysql-5.6.19 配置

    一 :准备阶段 1:php php-5.5.13下载链接:http://windows.php.net/downloads/releases/php-5.5.13-Win32-VC11-x64.zip ...

  10. Delphi笔记(GL_Scene四轴飞行器模型)

    有了前的一篇做铺垫,已经简单的说了GL_Scene的下载安装和一个简单的实例制作.现在就要开始制作一个3D的模型了,具体的步骤就不再这里多说了,直接上图和代码吧! [第一版]先看一下最开始的版本吧,比 ...