iOS下集成Lua与socket,cjson第三方库(非游戏引擎下)

Wesley13
• 阅读 813

文章首发于开源中国,这里是作者本人转载

公司的项目最近要使用Lua进行全平台的解析,iOS的集成在网上已经有了教程,但是lua三方库的集成一直出现错误。在混迹github,stack overflow许久后,终于在cocoa 2dx的相关问题中找到了一个合适的方法,在此总结成篇,以供各位参考。

先抛出几篇基础教程:

以上的文章如果没有基础,请仔细查看,看了又看才好。还有就是本教程不是为了一定解决问题,而是提供思路。

--------------------------------------------------------------------------------------------2015年02月10日上午

具体集成方法

  • 首先按第一篇文章加入lua库,也就是执行里面的“一、在XCODE中配置LUA”。这里注意,最好集成lua5.1版本不要使用5.2版本。因为第三方库对5.2的支持有些问题,如果你需要5.2版本lua的新特性,请自行寻找可用版的三方库。

  • 下载https://github.com/yangzhu6263736/cocos2dx-lua-ext里面的文件加入到工程里,里面luasocketscripts,lualoadexts文件是配置第三方库的配置文件,如果你要添加其他库,可以在这里进行修改。代码不复杂,请自己浏览理解。这里是.c里面的核心代码:

  • ?

    1

    2

    3

    4

    5

    6

    7

    socket  int  luaopen_socket(lua_State *L) {

    int  arg = lua_gettop(L);

    luaL_loadbuffer(L,( const  char *)B1, sizeof (B1), "socket.lua" );

    lua_insert(L,1);

    lua_call(L,arg,1);

    return  1;

    }

  • 现在就有了lua源码和第三方库,想要配置第三方库直接引入#include "lualoadexts.h",并在代码中使用lua_loadexts(lua_State*L)方法,就能简单的编译第三方库到程序中了。这里默认添加了cjson和socket两个库。具体的使用下面会提及。

  • 剩下的这里直接贴出代码,和相关解释。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

//

//  ViewController.m

//  lua

//

//  Created by Peter Kong on 15-1-6.

//  Copyright (c) 2015年 CrazyPeter. All rights reserved.

//

#import "ViewController.h"

#include "lualoadexts.h"

#include "lua.h"

#include "lualib.h"

#include "lauxlib.h"

/*

以下是宏定义代码,复制进去就好,不需要理解(其实一般用不到)

*/

#define NOERROR 0

#define LUA_PMCNT_CHECK(n)\

{ \

int  nParamCnt = lua_gettop(L) ; \

if ( nParamCnt != n ) \

{\

lua_pushnumber( L , -1 ) ; \

return  1 ; \

} \

}

#define LUA_RET_VALUE(n)\

{ \

lua_pushnumber( L , n );  \

return  1 ; \

}

#define LUA_OUT_ERROR(id) lua_pushnumber(L, id);if (id != 0) return 1;

/*

以上是宏定义代码,复制进去就好,不需要理解(其实一般用不到)

*/

/*

LUA相关代码部分

*/

unsigned  long  luaWorkTest( void * pParam)

{

//定义一个int变量来观测lua是否正常,后面有s1的地方都是判断方法是否正常调用成功

int  s1;

//为lua开启一块内存区(正式开始)

lua_State *L;

//启动lua的堆栈区状态(这个是根据名字随便猜的,估计类似于init方法)

L = luaL_newstate();

if  (L == NULL)

{

//lua程序执行有错误,此处会打印lua的错误行数,下同

NSLog(@ "error: %s \n"  , lua_tostring(L, -1));

return  -1;

}

//开启lua的基本使用库和注册相关函数(基本的加减发之类的简单函数方法库)

luaL_openlibs(L);

//加载第三方的函数库进入当前lua环境,这个在上面已经说明

//这里如果出了错误,要返回到lualoadexts文件里面查询第三方库的引用名称是否正确

luax_loadexts(L);

/*

1.注意,这里加载lua文件,我的需求是从网上下载lua代码,然后写入一个文件,存为.lua文件到本地,然后在这里调       用,网络下载和本地归档方法此处省略,如果不懂请自行百度。

2.NSString *logPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithForm      at:@"luaname.lua"]]  这个方法会报错,因为这是读取文件路径的方法,请自己拼凑lua文件地址

3.luaname.lua这个文件我有,但是你没有,请换成自己要使用的lua文件

*/

NSString *logPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@ "luaname.lua" ]];

//tmp1就是lua文件所在地址的utf8格式的字符串

//在lua源码里面要使用标注的c语言格式,所以用了char变量

const  char  * tmp1=  [logPath UTF8String];

NSLog(@ "tmp1 %s \n" ,tmp1);

//通过地址打开lua文件,放进lua环境中

s1 = luaL_loadfile(L, tmp1);

if  (s1 != 0)

{

NSLog(@ "error: %s \n"  , lua_tostring(L, -1));

lua_pop(L, 1);

return  -10;

}

//清空状态,这个代码要在开始结束时两次地方使用

lua_pcall(L, 0, 0, 0);

//lua_getglobal就是调用lua里面方法的方法了

lua_getglobal(L,  "func_printName" );

//lua_pushstring是用来传参的,相应的还有pushbool。pushint,视参数类型而定

lua_pushstring(L, tmp2);

printf ( "tmp2 = %s \n" ,tmp2);

/*

lua_pcall执行结果,里面的参数是

L:当前lua环境

1:传入的参数是1个

2:返回的参数是2个

0:执行正确的话result应该是0

*/

int  result = lua_pcall(L,1,2,0);

printf ( "result = %d\n" ,result);

if  (result != 0) {

//lua程序执行有错误,此处会打印lua的错误行数,下同

NSLog(@ "error-1: %s \n"  , lua_tostring(L, -1));

return  -10;

}

if  (result == 0) {

//lua_toboolean,lua_tostring是从堆栈区获得的返回结果,1,2分别表示返回的第一个参数,第二个参数

BOOL  b = lua_toboolean(L, 1);

const  char *tmp3 = lua_tostring(L, 2);

NSString *str = [NSString stringWithUTF8String:tmp3];

NSLog(@ "tmp3 - %s" ,tmp3);

NSLog(@ "b- %d" ,b);

//清除2个数据

lua_pop(L, 2);

}

//清空状态,这个代码要在开始结束时两次地方使用

lua_pcall(L, 0, 0, 0);

//关闭lua环境,防止内存溢出

lua_close(L);

return  0;

}

@interface ViewController ()

[@end](http://my.oschina.net/u/567204)

@implementation ViewController

- ( void )viewDidLoad

{

[super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

/*

开启一条线程使用lua,因为lua在程序里是开启一块空间,也就是一个堆栈区,这样不会影响整体程序的主线程。

*/

//这里使用了block语法来开启线程

dispatch_queue_t queue = dispatch_queue_create( "com.example.dothis" , NULL);

dispatch_async(queue, ^{

//NULL是参数,其实也就是标准的c语言调用方法,在luaWorkTest方法里我们定义了一个随意的指针,其实就是作为演示使用而已,没有具体含义

luaWorkTest(NULL);

});

}

/*

这个是在lua中注册的objective-c方法,当lua调用objective-c方法时会调用,但注意必需使用类方法,并且在.h文     件里面声明该方法(具体的原理请仔细研究推荐的第一篇文章)

*/

+( void )changeA:( int )as B:( int )bs

{

NSLog(@ "hahaTHEA:%d" ,as);

}

- ( void )didReceiveMemoryWarning {

[super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

[@end](http://my.oschina.net/u/567204)

  • 还有具体的lua和objective-c的交互请仔细看第一个文档中的lua_register(L,"logSomething", logYouWhat);相关内容

注意:

1.静态库问题:lua成为静态库后,给其他人或者真机测试如果出现问题,请去百度iOS静态库的封装。

2.由于环境版本不同会有出入,请多查看报错信息

3.这里贴出的代码是不能直接运行的,只是一个指导方向。

(打完,收工)

-------------------------------------------------------------------------------------------2015年02月10日下午

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
JS 苹果手机日期显示NaN问题
问题描述newDate("2019122910:30:00")在IOS下显示为NaN原因分析带的日期IOS下存在兼容问题解决方法字符串替换letdateStr"2019122910:30:00";datedateStr.repl
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这