SLua 中使用 Lua 5.3 的编译工程
2016-03-05 更新:
之前编译的库,在 Android 下 Lua_Number 和 Lua_Integer 被编译为了32位,导致从 C# 到 Lua 过程中有64位到32位整型转换会出现溢出出错,出现异常大的负整数。
以下修改或是之前遗漏的部分均使用红色表示。
2016-11-21 更新:
之前编译的库都是用的是 32位的 NDK(当时vs2015还不支持最新的64位ndk),如果你是用64位的 NDK 编译请注意兼容性问题;其二请注意安卓打包的库目录问题,安卓库 "libs"目录下对应于不同的cpu目录:
ARM 32: "armeabi-v7a"
ARM 64: "arm64-v8a"
x86 32: "x86"
x86 64: "x86_64"
我们项目将 SLua 中的 Lua 核心升级为了 5.3.,添加了 LPeg 和 sproto(和服务器兼容)。
整个工程直接分别创建了 Mac 和 IOS 的 XCode 工程,以及 Windows 和 Android 的 VS2015工程,vs 支持 clang 和 gcc 后,可以直接创建 Android NDK 工程。
安装 vs2015 的过程中,可以选择安装 Android 的支持,但是 NDK 以及其他工具的安装需要从谷歌下载,会导致这些组件安装失败,所以只能安装完成后,手动安装 NDK。
vs2015 只支持 NDK r10e 32位,使用更高版本将无法使用 clang,因为 vs2015默认且只支持 clang 3.,具体请阅读这里。各个 Android 需求工具的安装默认路径,请参考这里。
一个简单的办法是:将下载好的 NDK 放置在:“C:\ProgramData\Microsoft\AndroidNDK”,或其他地方,然后修改注册表:“HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0\Setup\VS\SecondaryInstaller\AndroidNDK”(没有则新建),然后新建项:“NDK_HOME”,设置值为 NDK 的安装路径即可完成。再次编译 NDK 工程则不会出现 "NDK_ROOT" 未定义的情况。
最简单的办法是:在安装时不勾选 Android SDK,NDK,自己单独下载,安装 vs2015 完毕后,在 工具 -> 选项 -> Cross Platform -> C++ -> Android 一栏修改路径即可。
使用 vs2015 编译 Android 版本 slua 需要注意的几个地方:
- 目前主流的 ARM 处理器都是带浮点处理单元的,即:“armeabi-v7a”,需要在 ARM 架构的配置中加入宏定义:“__ARM_ARCH_7A__”(实际在 vs2015 中编译的最低版本也是 armv7,不显式指定此宏也可以);
- 目前 支持 c99 的 NDK 至少为:“Jelly Bean 4.3.x,(android-18)”(属性页中的目标 API 级别),如果想兼容更低版本的 api,需要添加宏定义:“LUA_USE_C89”,否则会出现 error : undefined reference to 'log2' 错误,(属性页-> C/C++ -> 语言 -> C语言标准,不需要设置成 -std=c89,保持默认值:“默认”,可能依然导致编译错误。);(此处注意:一旦使用 LUA_USE_C89,那么 Lua_Number 和 Lua_Integer 就会被编译为32位,具体请参考 luaconf.h 中的代码,slua 中 lua_pushinteger 导出接口的定义默认使用的是 Int64,所以存在一个类型转换和溢出问题,你会发现无论你怎么调用 lua_pushinteger 到了 lua 端,数据都是错的,很可能是一个大的负整数,这就是我找了好几天才发现的错误,一个大坑。当然,你也可以在 slua 的 luadll.cs 中将 lua_pushinteger 导出接口的定义改为 Int32 应该也能修复,不过我没有试验并强烈建议使用 64 位整形的 Lua。)(2017-07-09更新:后来查看了 XLua 的工程编译并知道了,其实 log2 是 c99 的新函数,在 c98 中 lua 是通过两步运算模拟的,c99 中直接使用 log2 运算效率更高,所以如果为了支持 Android api 更低级别,只需要删除 math_log 中
#if !defined(LUA_USE_C89)
if (base == 2.0) res = l_mathop(log2)(x); else
#endif这一小段代码即可,影响就是在 log2 的运算中,效率稍低,但是兼容性更好了。)
- 可能编译 Lua 会出现错误:error : no member named 'decimal_point' in 'struct lconv',你可以修改 luaconf.h 中将
#define lua_getlocaledecpoint() (localeconv()->decimal_point[0])
修改为:
#define lua_getlocaledecpoint() ('.')但是这样修改了源文件会影响其他平台,所以更好的方式是,在工程属性页 -> C/C++ -> 命令行 -> 其他选项 中加入:-D "lua_getlocaledecpoint()=('.')" ,(引号也是内容一部分),这样修改仅限于 Android 平台编译;
- 如果出现各种连接错误:error : undefined reference to 'xxx',xxx 为各种数学函数 sin, cos 等等,需要给连接器增加 -lm 选项,动态查找链接接口:工程属性页 -> 链接器 -> 命令行 -> 其它选项 中加入:-lm 即可。
- 同时需要在工程 Debug 配置中加入宏定义:"LPEG_DEBUG"
- Mac 版本编译 Debug 版本,由于代码的一些书写(函数定义和使用)不符合 c99 书写标准,需要修改才能编译通过;
- Mac 版本编译的额外链接选项 Other Linker Flags 需要加入:“-undefined dynamic_lookup”;
- 默认 Lua 的异常使用 longjmp,如果编译为 c++ 会自动转换为 try-catch,如果在c++工程中编译 c 代码,由于已经定义 _cplusplus,LUAI_THROW 会被展开为 try,出现编译错误的话可以考虑添加宏:LUA_USE_LONGJMP。
编译工程 SLua + Lua 5.3.2 + LPeg 1.0.0 + sproto 的 GitHub 地址:https://github.com/yaukeywang/slua-503-build
后续:由于 premake5 目前对 vs2015 的支持还不完整,打算利用业余时间扩展 premake5,同时将改工程修改为 premake5 工程并提交到 github。
SLua 中使用 Lua 5.3 的编译工程的更多相关文章
- slua 中使用 lua5.3
因为我们服务器极有可能要迁移到 skynet 上,它基于 lua5.3,而服务器和客户端会公用很多lua代码,所以在考虑在客户端 slua 中使用 lua5.3. 经过编译后,发现 slua 对 lu ...
- vs如何在C++中调用Lua
最近Cocos2dx的学习卡壳了,一般的照抄代码我不想写上来,但想示例也想得我头晕...为了放松大脑调整状态于是开始学习Lua.Lua的语法学习还是比较简单的,学过javascript或者vbscri ...
- vs2013如何在C++中调用Lua(二)
Lua学习笔记 vs2013如何在C++中调用Lua (此为转载教程) 本人试过完全可行 一.准备工作 1.下载Lua源码,地址:http://www.lua.org/download.html(我用 ...
- C++中嵌入Lua脚本环境搭建
第一步(环境准备工作): 工具: ●LuaForWindows_v5.1.4-46.exe傻瓜式安装. 作用:此工具可以在windows环境下编译运行Lua脚本程序.安装完成后会有两个图标:Lua和S ...
- Qt学习笔记:Qt中使用Lua
今天想在Qt中使用Lua进行数据操作 结果发现在Qt中使用Lua的文章较少,虽然很简单,但是还是写出来提供入门,顺便记录一下 我使用的是Qt Creator 3.4.2,用的是mingw4.9.2的编 ...
- lua学习:游戏中的Lua
lua作为一种脚本语言,可以快速地开发游戏的原型.提高游戏的开发效率. 在游戏中,lua可以用来完成下面这些工作: ●编辑游戏的用户界面 ●定义.存储和管理基础游戏数据 ●管理实时游戏事件 ●创建和维 ...
- 在 slua 中使用更新的面向对象方案
上一篇记录了我使用 Slua.Class 来实现面向对象扩展 C# 中得类,但实际使用中,更多地情况是直接在 lua 中定义基类然后扩展,于是触发了我重新思考下是否两种形式应该统一用一种,目前的方案中 ...
- Java中使用Lua脚本语言(转)
Lua是一个实用的脚本语言,相对于Python来说,比较小巧,但它功能并不逊色,特别是在游戏开发中非常实用(WoW采用的就是Lua作为脚本的).Lua在C\C++的实现我就不多说了,网上随便一搜,到处 ...
- redis中使用lua脚本
lua脚本 Lua是一个高效的轻量级脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能 使用脚本的好处 1.减少网络开销,在Lua脚 ...
随机推荐
- IO流中的文件创建并且写入读取
package com.java.inoutputstreamDmeo.www; import java.io.File;import java.io.FileInputStream;import j ...
- zoj1873 Let it Bead
思路:polya裸题,如果是旋转,对于旋转i格的循环节长度len=lcm(i,n)/i,个数就是n/len=gcd(i,n):如果是翻转,奇数个点对称轴就是一个点一条边,那么循环节个数即n/2+1, ...
- (hdu)1042 N! 大数相乘
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1042 Problem Description Given an integer N( ≤ ...
- 负载均衡集群中的session解决方案
前言 在我们给Web站点使用负载均衡之后,必须面临的一个重要问题就是Session的处理办法,无论是PHP.Python.Ruby还是Java,只要使用服务器保存Session,在做负载均衡时都需要考 ...
- JS脚本延时
JS脚本延时 function sleep(milliseconds) { var start = new Date().getTime(); for (var i = 0; i < 1e7 ...
- js禁止高频率连续点击思路
1.类似react的数据流,点击之后立即设置值为空,当返回值后才可以点击 2.设置定时器,每次进入之前先清空掉定时器,然后开启定时器 <main> <div id="me& ...
- textarea 超过字数
<textarea name="></textarea> <div id="statementRowChk"></div> ...
- 在 Linux 命令行中使用和执行 PHP 代码
PHP是一个开源服务器端脚本语言,最初这三个字母代表的是“Personal Home Page”,而现在则代表的是“PHP:Hypertext Preprocessor”,它是个递归首字母缩写.它是一 ...
- corosync+pacemaker and drbd实现mysql高可用集群
DRBD:Distributed Replicated Block Device 分布式复制块设备,原理图如下 DRBD 有主双架构和双主架构的,当处于主从架构时,这个设备一定只有一个节点是可以读写的 ...
- b+树 b-树的区别
B+树与B*树小结 一.B+树 1.B+树定义与特性 B+树是B-树的变体,也是一种多路搜索树: 其定义基本与B-树同,除了: 1).非叶子结点的子树指针与关键字个数相同: 2).非叶子结点的子树指针 ...