tolua库跨平台编译

tolua框架有两部分组成,一个是c#部分,一个是c部分,整个框架在游戏代码中的位置如下图所示:
这里写图片描述
可以看到tolua c起到承上启下的作用,是c#和lua之间进行堆栈交互的中间层。所以如果我们要为tolua c扩展功能的话,就必须把tolua c进行重新编译成对应平台的tolua库,供c#和lua进行调用。其中tolua地址为https://github.com/topameng/tolua,对应的tolua运行时地址为https://github.com/topameng/tolua_runtime

一.编译win32和win64平台的tolua.dll库
1.配置mingw:可以参考https://github.com/topameng/tolua_runtime/wiki进行配置,其中配置好的mingw地址为https://pan.baidu.com/s/1c2JzvDQ
2.编辑build_win32.sh或者build_win64.sh文件,在里面添加或者移除第三方c库。以默认的build_win64.sh中添加sproto为例,配置如下:

#!/bin/bash
# 64 Bit Version
mkdir -p window/x86_64

cd luajit-2.1
mingw32-make clean

mingw32-make BUILDMODE=static CC="gcc -m64 -O2" XCFLAGS=-DLUAJIT_ENABLE_GC64
cp src/libluajit.a ../window/x86_64/libluajit.a
mingw32-make clean

cd ..

gcc -m64 -O2 -std=gnu99 -shared \
 tolua.c \
 int64.c \
 uint64.c \
 pb.c \
 lpeg.c \
 sproto.c \
 lsproto.c \
 struct.c \
 cjson/strbuf.c \
 cjson/lua_cjson.c \
 cjson/fpconv.c \
 luasocket/auxiliar.c \
 luasocket/buffer.c \
 luasocket/except.c \
 luasocket/inet.c \
 luasocket/io.c \
 luasocket/luasocket.c \
 luasocket/mime.c \
 luasocket/options.c \
 luasocket/select.c \
 luasocket/tcp.c \
 luasocket/timeout.c \
 luasocket/udp.c \
 luasocket/wsocket.c \
 -o Plugins/x86_64/tolua.dll \
 -I./ \
 -Iluajit-2.1/src \
 -Iluasocket \
 -lws2_32 \
 -Wl,--whole-archive window/x86_64/libluajit.a -Wl,--no-whole-archive -static-libgcc -static-libstdc++

3.打开ming32.exe或者ming64.exe的终端,并选择编辑好的build_win32.sh或者build_win64.sh文件进行编译,最终会生成一个tolua.dll文件到Plugins/x86或者Plugins/x86_64目录下。将编译好的tolua.dll拷贝到unity的Plugins下对应平台目录下进行替换。

二.编译android平台下arm和x86架构的libtolua.so库:由于android机器用的cpu架构最多的是acorn公司的arm架构,所以intel公司的x86架构也做了一个arm架构转换程序。所以我们一般只需要导出arm架构的libtolua.so库就行,但是有时有可能因为转换程序的问题,在x86架构机器上会出现闪退,所以最好也导出x86架构的libtolua.so库,但这样就会增加包体大小。编译android的libtolua.so库步骤如下:
1.安装ndk,下载地址为https://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip,下载安装完毕后配置ndk环境变量,如图所示:
这里写图片描述
2.编辑build_arm.sh或者build_x86.sh文件,修改ndk路径为自己ndk所在的路径,如上面环境变量地址:D:\Program\android-ndk-r10e。
3.修改android/jni目录下面的Android.mk文件,在里面添加或者移除第三方c库。以默认的Android.mk中添加sproto为例,配置如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libluajit
LOCAL_SRC_FILES := libluajit.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE := tolua
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../luajit-2.1/src
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../

LOCAL_CPPFLAGS := -O2
LOCAL_CFLAGS :=  -O2 -std=gnu99
LOCAL_SRC_FILES :=  ../../tolua.c \
                    ../../int64.c \
                    ../../uint64.c \
                    ../../pb.c \
                    ../../lpeg.c \
                    ../../sproto.c\
                    ../../lsproto.c\
                    ../../struct.c \
                    ../../cjson/strbuf.c \
                    ../../cjson/lua_cjson.c \
                    ../../cjson/fpconv.c \
                    ../../luasocket/auxiliar.c \
                    ../../luasocket/buffer.c \
                    ../../luasocket/except.c \
                    ../../luasocket/inet.c \
                    ../../luasocket/io.c \
                    ../../luasocket/luasocket.c \
                    ../../luasocket/mime.c \
                    ../../luasocket/options.c \
                    ../../luasocket/select.c \
                    ../../luasocket/tcp.c \
                    ../../luasocket/timeout.c \
                    ../../luasocket/udp.c \
                    ../../luasocket/usocket.c \

LOCAL_WHOLE_STATIC_LIBRARIES += libluajit
include $(BUILD_SHARED_LIBRARY)

4.打开ming32.exe终端,并选择build_arm.sh或者build_x86.sh文件进行编译,此时ndk会将luajit目录生成luajit.a文件放在android/jni目录下,并和Android.mk文件一起通过gcc编译,最终会生成一个libtolua.so文件到Plugins/Android/libs/armeabi-v7a或者Plugins/Android/libs/x86目录下。将编译好的libtolua.so拷贝到unity的Plugins下对应平台目录下进行替换。

tolua中更改第三方c库:tolua库中添加或者移除第三方c库后,需要在tolua的LuaDLL.cs文件中添加或者移除第三方c库的导出函数。还是以加上sproto为例,对应的lsproto.c库入口函数如下:

int luaopen_sproto_core(lua_State *L) {
#ifdef luaL_checkversion
    luaL_checkversion(L);
#endif
    luaL_Reg l[] = {
        { "newproto", lnewproto },
        { "deleteproto", ldeleteproto },
        { "dumpproto", ldumpproto },
        { "querytype", lquerytype },
        { "decode", ldecode },
        { "protocol", lprotocol },
        { "loadproto", lloadproto },
        { "saveproto", lsaveproto },
        { "default", ldefault },
        { NULL, NULL },
    };
    //luaL_newlib(L,l);
    luaL_register(L, "sproto.core", l);
    pushfunction_withbuffer(L, "encode", lencode);
    pushfunction_withbuffer(L, "pack", lpack);
    pushfunction_withbuffer(L, "unpack", lunpack);
    return 1;
}

此时LuaDLL.cs中关联的导出函数为:

[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
public static extern int luaopen_sproto_core(IntPtr L);

参考地址https://www.jianshu.com/p/5a35602adef8

猜你喜欢

转载自blog.csdn.net/zjz520yy/article/details/79777408
今日推荐