源码
游戏项目中遇到的狗屎问题,分享一下解决经验,以一个最基本的程序为例:
test.c
c
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static int about(lua_State *L){
lua_pushstring(L,"test by flaribbit");
return 1;
}
static const struct luaL_Reg funcList[]=
{
{"about", about},
{0, 0}
};
int luaopen_test(lua_State *L)
{
luaL_register(L, "test", funcList);
return 1;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
编译
windows 和 linux
在windows系统和linux系统中,可以直接使用gcc编译,注意链接lua51.dll
或者libluajit.so
,记得改掉下面命令中的path/to/
bash
gcc test.c path/to/lua51.dll -s -O2 -DNDEBUG -o test.dll
1
bash
gcc test.c path/to/libluajit.so -s -O2 -DNDEBUG -o libtest.so
1
然后在lua中调用require"test"
就可以导入使用了,打包游戏的时候记得把库放在外面,和love.dll
放在一起,不要塞进game.love
或者exe
android系统就比较恶心了,自备NDK,以下教程写于windows系统,在test.c
所在的目录创建Android.mk
和Application.mk
,下面的代码中记得修改path/to/
,为liblove.so所在的目录(可以直接解压love2d的安装包拿)
安卓
Android.mk
makefile
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := test.c
LOCAL_LDFLAGS := -Lpath/to/$(TARGET_ARCH_ABI) -llove
LOCAL_C_INCLUDES := include
include $(BUILD_SHARED_LIBRARY)
1
2
3
4
5
6
7
2
3
4
5
6
7
Application.mk
makefile
APP_CPPFLAGS := -frtti
APP_LDFLAGS := -latomic
APP_ABI := armeabi-v7a arm64-v8a
APP_PLATFORM := android-16
APP_OPTIM := release
1
2
3
4
5
2
3
4
5
然后调用ndk-build
编译,日常记得修改path/to/
bash
path/to/ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk APP_BUILD_SCRIPT=Android.mk
1
会报可能错误链接的warning,问题不大,编译完成后会在libs
文件夹里得到两个libtest.so
调用
最后编写lua程序,这里有个巨坑,*.so
必须放到/data/data/package.name
里面才能被require
正确加载,否则会爆类似下面的神秘错误
txt
Error
error loading module 'test' from file '/sdcard/libtest.so':
dlopen failed: library "/sdcard/libtest.so" needed or dlopened by "/data/app/org.love2d.android.embed-cfg2TKQ-XsSj13FxWVvTUw==/lib/arm64/liblove.so" is not accessible for the namespace "classloader-namespace"
Traceback
[C]: at 0x7a3d813a7c
[C]: in function 'require'
/sdcard/prog.lua:2: in main chunk
[C]: in function 'require'
main.lua:2: in main chunk
[C]: in function 'require'
[C]: in function 'xpcall'
[C]: in function 'xpcall'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
那么问题来了,如何放到/data/data/package.name
里面呢…?
把*.so
文件打包进game.love
,然后用下面的代码copy到save文件夹里,也算是个办法吧。
lua
package.cpath='/data/data/org.love2d.android.embed/files/save/archive/lib?.so;'..package.cpath
love.filesystem.write("libtest.so", love.filesystem.read("libtest.so"))
require "test"
1
2
3
2
3
it just works