博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Cocos2d-x中使用第三方so库
阅读量:6234 次
发布时间:2019-06-22

本文共 4926 字,大约阅读时间需要 16 分钟。

项目中假设使用到第三方的SDK,大多数是以.so动态共享库的文件打包给我们使用。怎样使用他们,见以下分析。

1、获得库文件

假如我们得到的库文件是libxxx.so(注:关于.so文件的命名方式,可百度)。

在Jni文件夹下新建prebuilt文件夹,把获得的库文件

复制到该目录下。

2、使用库文件

库文件的使用须要改动Android.mk,在mk文件里增加下面代码:
include $(CLEAR_VARS)  LOCAL_MODULE := xxx  LOCAL_SRC_FILES := prebuilt/libxxx.so  include $(PREBUILT_SHARED_LIBRARY)    LOCAL_SHARED_LIBRARIES := xxx

Java中调用

static {        System.loadLibrary("XXX");        System.loadLibrary("cocos2dcpp");} 

3、编译

编译后会在libs/armeabi文件夹下生产我们须要的libxxx.so文件,并编译到APK中。

4、万普样例

下面是万普平台Demo的mk文件,在这贴出来。让大家体会下面用法。
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := uninstall  //第一步LOCAL_SRC_FILES := prebuilt/libuninstall.so   //第二步include $(PREBUILT_SHARED_LIBRARY)            //第三步include $(CLEAR_VARS)$(call import-add-path,$(LOCAL_PATH)/../../cocos2d)$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/external)$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/cocos)LOCAL_MODULE := cocos2dcpp_sharedLOCAL_MODULE_FILENAME := libcocos2dcpp  //将引用的库加上cpp源文件共同打包出libcocos2dcpp库LOCAL_SRC_FILES := hellocpp/main.cpp \                   ../../Classes/AppDelegate.cpp \                   ../../Classes/HelloWorldScene.cpp\                   ../../Classes/WapsAd.cppLOCAL_C_INCLUDES := $(LOCAL_PATH)/../../ClassesLOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_staticLOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_staticLOCAL_WHOLE_STATIC_LIBRARIES := cocos_extension_staticLOCAL_WHOLE_STATIC_LIBRARIES += box2d_staticLOCAL_WHOLE_STATIC_LIBRARIES += cocostudio_static# LOCAL_WHOLE_STATIC_LIBRARIES += box2d_static# LOCAL_WHOLE_STATIC_LIBRARIES += cocosbuilder_static# LOCAL_WHOLE_STATIC_LIBRARIES += spine_static# LOCAL_WHOLE_STATIC_LIBRARIES += cocostudio_static# LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static# LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_staticinclude $(BUILD_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_SHARED_LIBRARIES := uninstall     //第四步$(call import-module,.)$(call import-module,audio/android)$(call import-module,Box2D)$(call import-module,editor-support/cocostudio)$(call import-module,extensions) # $(call import-module,Box2D)# $(call import-module,editor-support/cocosbuilder)# $(call import-module,editor-support/spine)# $(call import-module,editor-support/cocostudio)# $(call import-module,network)# $(call import-module,extensions)
注意事项
在主java文件里找到System.loadLibrary("cocos2dcpp");这句,然后在以下相同添上你要载入的三方库名称就可以。

貌似默认不指明的话,会到系统路径下去找so文件(没有root或system的权限。无权对这个文件夹操作),这几个so按道理是会装到data/appname/lib文件夹下的。

载入顺序

这里有个问题要尤其注意,就是这些动态库的载入顺序,
一定要放到libcocos2dcpp前载入。否则在载入libcocos2dcpp时。会由于没有之前这两个依赖的动态库而报错,报的就是相应的动态库木有载入

Android可行载入第三方库文档,转载自:http://blog.csdn.net/smfwuxiao/article/details/8523479

Android NDK r5 開始支持预编译库(动态库和静态库),即程序能使用库的预编译版本号。

该特性可用于下面双方面:

1)向第三方NDK开发者公布你的共享库而不用提供源代码。

2)使用一个提前编译好的库(预编译库)来加速编译过程。

本文说明该特性怎样工作。

I. 声明一个预编译库的模块

对于Android编译工具而言,每一个预编译库必须声明为一个独立的模块。这里举一个样例。如果 libfoo.so 文件与 Android.mk 位于同一个文件夹:
[plain] 
  1. LOCAL_PATH := $(call my-dir)  
  2. include $(CLEAR_VARS)  
  3. LOCAL_MODULE := foo-prebuilt  
  4. LOCAL_SRC_FILES := libfoo.so  
  5. include $(PREBUILT_SHARED_LIBRARY)  
按下面步骤声明这样一个模块:
1. 给该模块取一个名字(这里是 foo-prebuilt)。这个名字不须要与预编译库自身的名字同样。

2. 将 LOCAL_SRC_FILES 指定为你要提供的共享库的路径。通常,该路径是相对于 LOCAL_PATH 的路径。

注意:必须保证共享库ABI的兼容性。

3. 假设你的库是共享库,则包括 PREBUILT_SHARED_LIBRARY 而不是 BUILD_SHARED_LIBRARY。假设是静态库,则包括 PREBUILT_STATIC_LIBRARY。

预编译模块不须要编译。

该预编译模块会被复制到 $PROJECT/obj/local 以下。还会被复制到 $PROJECT/libs/<abi> 以下(这里的库被strip过)。

II. 在其它模块中引用这个预编译库

在依赖该预编译库的模块相应的Android.mk中,将预编译库的名字(前面取的)增加到 LOCAL_STATIC_LIBRARIES 或 LOCAL_SHARED_LIBRARIES 声明中。比如,一个使用上面libfoo.so的简单样例例如以下:

[plain] 
  1. include $(CLEAR_VARS)  
  2. LOCAL_MODULE := foo-user  
  3. LOCAL_SRC_FILES := foo-user.c  
  4. LOCAL_SHARED_LIBRARIES := foo-prebuilt  
  5. include $(BUILD_SHARED_LIBRARY)  

III. 将预编译库的头文件导出

得到预编译库之后。一般须要它相应的头文件。比如前面的libfoo.so,它有相应的foo.h。编译依赖libfoo.so的模块时。须要将该头文件和它的路径提供给NDK编译系统。一种简单方法是,前面在定义该预编译库的时候,使用LOCAL_EXPORT_C_INCLUDES 变量。

比如。如果文件 foo.h 位于当前预编译模块所在文件夹的 include 子文件夹,则能够在预编译模块的Android.mk文件里编写例如以下:

[plain] 
  1. include $(CLEAR_VARS)  
  2. LOCAL_MODULE := foo-prebuilt  
  3. LOCAL_SRC_FILES := libfoo.so  
  4. LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include  
  5. include $(PREBUILT_SHARED_LIBRARY)  
这个 LOCAL_EXPORT_C_INCLUDES 定义确保了不论什么依赖这个预编译库的模块会自己主动在自己的 LOCAL_C_INCLUDES 变量中添加到这个预编译库的include文件夹的路径。从而可以找到当中的头文件。

IV. 调试预编译库

建议你在预编译库中保留调试信息。位于 $PROJECT/libs/<abi> 的版本号都是不含调试信息的(被NDK编译系统运行strip过的)。调试版的库才干用于 ndk-gdb。

V. 共享库ABI的选择

如前所述,共享库与目标系统的ABI兼容性至关重要。应检查一下 TARGET_ARCH_ABI 的值,能够是下面值:

armeabi        目标系统CPU是ARMv5TE或更高
armeabi-v7a    目标系统CPU是ARMv7或更高
x86            目标系统CPU是x86
注意。armeabi-v7a的CPU能够非常好地运行armeabi的程序。

举一个样例。我们提供一个预编译库的两个版本号,然后选择不同的ABI:

[plain] 
  1. include $(CLEAR_VARS)  
  2. LOCAL_MODULE := foo-prebuilt  
  3. LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libfoo.so  
  4. LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include  
  5. include $(PREBUILT_SHARED_LIBRARY)  
这里如果要拷贝的预编译库所在的文件夹结构例如以下:
    Android.mk            --> 编译这个预编译库的Android.mk
    armeabi/libfoo.so     --> armeabi版本号的共享库
    armeabi-v7a/libfoo.so --> armeabi-v7a版本号的共享库
    include/foo.h         --> 预编译库导出的头文件
注意:你不必提供armeabi-v7a版本号,由于armeabi版本号的共享库可以被armeabi-v7a的兼容,可是反过来就不行。

你可能感兴趣的文章
MongoDB、Hbase、Redis等NoSQL优劣势、应用场景
查看>>
NodeJs如何全局统一处理异常,实现RestFull风格
查看>>
算法基础之经典算法
查看>>
从外部连接Broadleaf Demo数据库
查看>>
编程大牛 Bruce Eckel 对新程序员的忠告
查看>>
一次踩坑经历看vue几个组件通信的适用场景
查看>>
MySQL的语句执行顺序
查看>>
JavaScript基础语法 变量 常量 数据类型
查看>>
Java™ 教程(仔细看看“Hello World!”应用程序)
查看>>
flutter中的异步
查看>>
tensorflow学习之Anaconda开发环境搭建
查看>>
[JS]《你不知道的Javascript·上》——this关键字
查看>>
如何理解 (object.getName = object.getName)() 这段代码?
查看>>
Spring AOP 源码分析系列文章导读
查看>>
Linux - 系统 - 文件目录
查看>>
[LeetCode] 267. Palindrome Permutation II
查看>>
前端妹纸的进阶之路——redux源码分析
查看>>
Centos7下使用gitolite搭建git服务器
查看>>
如何更好的编写async函数
查看>>
【前端工程师手册】JavaScript之this的笔记
查看>>