编译Lua lib for Android – 成功,但奇怪的segfaults
对不起长期的问题.如果你愿意,请跳过关于编译Lua的部分(几乎可以),并直接得到最后一个问题.
我们来编译Lua库,就像Android的静态库. 下载最新的来源,并查看doc / readme.html – 在其他系统部分构建Lua部分,以供编译的文件列表. 当然看看makefile – 看看什么是休闲的方式我们必须设置平台标志是linux,bsd e.t.c.但是当然没有Android平台,所以我们可以选择将平台设置为ANSI,Linux,Posix或Generic. 第一个问题:它建立好(有一个例外,关于llex.c,我将在下面描述),即使没有任何平台标志,所以也许这是不必要的? 我设置ANSI标志. Android.mk LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := lua LOCAL_CFLAGS := -DLUA_ANSI LOCAL_SRC_FILES := lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c ltm.c lundump.c lvm.c lzio.c lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c include $(BUILD_STATIC_LIBRARY) Application.mk APP_MODULES := lua APP_PLATFORM := android-8 APP_OPTIM := release APP_ABI := armeabi 当然有错误 Compile thumb : lua <= llex.c jni/llex.c: In function 'trydecpoint': jni/llex.c:214:18: error: 'struct lconv' has no member named 'decimal_point' #if !defined(getlocaledecpoint) #define getlocaledecpoint() (localeconv()->decimal_point[0]) //Missing struct member #endif 以最便宜的方式解决它 #if !defined(getlocaledecpoint) #define getlocaledecpoint() ('.') //Code-monkey style #endif Android NDK中的locale.h有一些限制,所以这个错误并不奇怪. 还有关于size_t,UCHAR_MAX,INT_MAX的错误 – 将llimits.h包含到llex.c中,所有错误都已经消失了. 现在只有在静态int llex中存在关于“在案件结束时缺少断点”和“不返回函数返回非空”的警告,但是我们不再混淆Lua源代码,因为它不是至关重要的. 第二个问题:我要去编程人员地狱这样的快速修复? 在obj / armeabi目录中抓住我们新鲜烘焙的LuaLib,并进行测试. TestLua – Android.mk LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := lua LOCAL_SRC_FILES := liblua.a LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/lua-inc //Where .h files from lua src stored include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := LuaLibTest LOCAL_STATIC_LIBRARIES:= lua LOCAL_SRC_FILES := LuaLibTest.c LOCAL_LDLIBS := -llog include $(BUILD_SHARED_LIBRARY) LuaLibTest.c #include "LuaLibTest.h" #include "lua-inc/lua.h" #include "lua-inc/lauxlib.h" #include <android/log.h> #define INFO_TAG "[INFO]" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,INFO_TAG,__VA_ARGS__) JNIEXPORT void JNICALL Java_com_lualib_test_NativeLib_testLua(JNIEnv* env,jclass _class) { LOGI("HI FROM C"); lua_State* L = luaL_newstate(); luaL_openlibs(L); lua_pushstring(L,"Some string from Android C" ); lua_setglobal(L,"TEST" ); lua_getglobal(L,"TEST" ); const char* res = lua_tostring(L,lua_gettop(L)); LOGI("LUA TEST VAL: %s",res); lua_pop(L,1); lua_close(L); } 如果我们用AssetManager读取脚本文件并将其内容放入到lual_dostring()中的字符串中,它也可以工作.所以是的,我们为Android构建lua(除了lua i / o函数,这将不起作用,因为像printf这样的stdio在Android NDK中不起作用). 然而,这个构建有奇怪的错误,例如 – 每帧的fps脚本更新,但是随着下一个错误在下一个错误,它可能会下降什么更新帧与帧增量时间 FPS.lua FPS = {} function initFPS() FPS.fps = 0 FPS.last_fps = 0 FPS.frames_count = 0 FPS.frames_time = 0.0 local fps_msg = "FPS: " .. FPS.fps c_set_fps(fps_msg);//Set some label in app - c function end function updateFPS(frameDeltaTime) FPS.frames_count = FPS.frames_count + 1 FPS.frames_time = FPS.frames_time + frameDeltaTime if FPS.frames_time >= 1000.0 then FPS.frames_time = 0.0; FPS.fps = FPS.frames_count; FPS.frames_count = 0; if FPS.last_fps ~= FPS.fps then local fps_msg = "FPS: " .. FPS.fps c_set_fps(fps_msg); FPS.last_fps = FPS.fps end end end FPS.c void update_fps(const double* frame_delta_time) //SEGFAULT at this,at random time { lua_State* l = get_lua(); lua_getglobal(l,"updateFPS"); lua_pushnumber(l,*frame_delta_time); lua_call(l,1,0); } 并在随机时间(1分钟 – 3分钟)获得下一个错误消息与整个应用程序崩溃 最后一个问题(是的,你做了/跳过无聊的部分) 我认为是因为Android / Java垃圾清理器和Lua垃圾清理器的冲突,所以有些尝试释放的内存已经释放了. 编辑 – 从双重指针和为什么: #define MS_1_SEC 1000.0 typedef struct time_manager { double _time; double delta_time; }time_manager; static double get_ms(s_time* time)//get time in ms { return MS_1_SEC * time->tv_sec + (double) time->tv_nsec / NS_1_SEC; } double get_time_now() { s_time time_now; clock_gettime(CLOCK_REALTIME,&time_now); return get_ms(&time_now); } void init_time_manager(time_manager* tm) { tm->_time = get_time_now(); tm->delta_time = 0.0; } void update_time_manager(time_manager* tm) { double time_now = get_time_now(); tm->delta_time = time_now - tm->_time; tm->_time = time_now; } static time_manager TM;//Global static var for whole render module 在onInit()函数中 init_time_manager(&TM); 在onDraw()函数中 double* frame_time = &TM.delta_time;//get pointer to delta time update_ui(frame_time);//Pass it every function update_sprites(frame_time); update_fps(frame_time); ... draw_fps(); update_time_manager(&TM); 为什么我使用指针双重而不是双重?那么它可以节省4个字节的复制(每个指针的大小为4,double的大小为8)frame_delta_time参数到每个函数像update_ui(),我对每个大于4个字节的struct / type都做同样的事情,const指针而不是just struct x用于只读访问.这是坏事吗? 解决方法
您的更改看起来非常适合您的系统. lua邮件列表表明您对luaconf.h进行了更改,而不是llex.c(
http://lua-users.org/lists/lua-l/2012-08/msg00100.html),但这并不重要. (所以简而言之,你不会去这些变化的地狱…).
我猜是因为某些C-lua大桥正在做一些“坏”事情,发生了这样的事件.我的猜测将是某种lua stack over / under flow,或者通过使用无效的索引访问lua堆栈.如果您可以在linux / os x上构建桥接器,并使用valgrind,您可能可以跟踪这一点. (Windows也存在类似的工具,但是我不确定android的本机) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |