Cocos2d-x中使用第三方so库

2023-11-04

项目中如果使用到第三方的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中调用

<span style="background-color: rgb(0, 204, 204);">static {
        System.loadLibrary("XXX");
        System.loadLibrary("cocos2dcpp");
} </span>

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_shared

LOCAL_MODULE_FILENAME := libcocos2dcpp  //<span style="background-color: rgb(0, 204, 204);">将引用的库加上cpp源文件共同打包出libcocos2dcpp库
</span>
LOCAL_SRC_FILES := hellocpp/main.cpp \
                   ../../Classes/AppDelegate.cpp \
                   ../../Classes/HelloWorldScene.cpp\
                   ../../Classes/WapsAd.cpp

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes

LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static
LOCAL_WHOLE_STATIC_LIBRARIES := cocos_extension_static
LOCAL_WHOLE_STATIC_LIBRARIES += box2d_static
LOCAL_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_static

include $(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]  view plain copy
  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]  view plain copy
  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]  view plain copy
  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]  view plain copy
  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的兼容,但是反过来就不行。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cocos2d-x中使用第三方so库 的相关文章

  • getItem 与 getItemAtPosition

    有两种方法可以获取列表视图中的选定项目 list getAdapter getItem position list getItemAtPosition position 我的问题是 哪一种是首选的做法 我见过人们同时使用这两种方法 您可以使
  • 如何更新 Firebase 中的节点密钥?

    如何重命名14 04 2017 node 没有用于重命名节点的 API 您必须获取节点的值 使用新名称将其保存到数据库并删除旧节点
  • 为什么将函数参数声明为最终的?

    我目前正在阅读 Sams 出版的 24 小时自学 Android 应用程序开发 一书 我对 Java Android 或其他方面还比较陌生 我对 ActionScript 3 有非常扎实的背景 它与 Java 有足够的相似之处 因此该语言本
  • 菜单未显示在应用程序中

    由于某种原因 我的操作菜单在我的 Android Studio 应用程序中消失了 我正在按照教程学习如何创建 Android 应用程序 但最终遇到了这个问题 我正在使用 atm 的教程 http www raywenderlich com
  • Delphi XE7 Android 全屏(隐藏软键)

    如何在XE7中全屏显示 隐藏顶部 标题 和底部 软键 工具栏 在 XE6 中 我可以通过在应用程序部分写入来调整 AndroidManifest 以使我的应用程序全屏显示并且没有操作栏 android theme android style
  • 在 Android 中使用 DataOutputStream 在 POST 正文中发送特殊字符 (ë ä ï)

    我目前正在开发一个具有大量服务器端通信的 Android 应用程序 昨天 我收到一份错误报告 称用户无法发送 简单 特殊字符 例如 我搜索过但没有找到任何有用的东西 可能重复 没有答案 https stackoverflow com que
  • Android 版 Robotium - solo.searchText () 不起作用

    我在使用 Robotium 时遇到 searchText 函数问题 我正在寻找这个字符串
  • CookieManager.getInstance().removeAllCookie();不删除所有cookie

    我在应用程序的 onCreate 中调用 CookieManager getInstance removeAllCookie 我遇到了一个奇怪的问题 我看到 GET 请求中传递了意外的 cookie 值 事实上 cookie 值是一个非常非
  • 在 Jetpack Compose 中启动动画矢量 Drawable

    我有一个动画矢量可绘制R drawable my anim 我想在 Jetpack Compose 中展示并开始 可绘制对象显示 渲染正确 但动画未启动 这是撰写视图 Composable fun SplashView Surface mo
  • MediaCodec 创建输入表面

    我想使用 MediaCodec 将 Surface 编码为 H 264 使用 API 18 有一种方法可以通过调用 createInputSurface 然后在该表面上绘图来对表面中的内容进行编码 我在 createInputSurface
  • 如何在C(Linux)中的while循环中准确地睡眠?

    在 C 代码 Linux 操作系统 中 我需要在 while 循环内准确地休眠 比如说 10000 微秒 1000 次 我尝试过usleep nanosleep select pselect和其他一些方法 但没有成功 一旦大约 50 次 它
  • 从 android 简单上传到 S3

    我在网上搜索了从 android 上传简单文件到 s3 的方法 但找不到任何有效的方法 我认为这是因为缺乏具体步骤 1 https mobile awsblog com post Tx1V588RKX5XPQB TransferManage
  • Android Webview 图像未加载

    我制作了一个简单的应用程序WebView 但有些图片无法加载 正确 在我的电脑上 错误 在模拟器中 Correct 错误 没有横幅 于是我用Chrome debug进行调试 发现我的代码被改变了 我不添加像noscript or style
  • 材质设计图标颜色

    应该是哪种颜色 暗 材质图标 在官方文档上 https www google com design spec style icons html icons system icons https www google com design s
  • 如何将设备连接到Eclipse?

    我无法解决这个简单的问题 我正在尝试通过 USB 电缆将我的设备连接到 Eclipse 在我的 PC 上 我已经安装了 Eclipse 和 Android SDK 并且在模拟器上运行该程序运行良好 我已在我的电脑上下载并安装了 Samsun
  • 在 Android 上按下电源按钮时,如何防止先调用 onDestroy() 再调用 onCreate()

    我正在记录每个 onCreate 和 onDestroy 调用 我发现 一旦我单击 Android 上的电源按钮 以及模拟器上的电源按钮 我的活动中就会拨打电话 gt onDestroy gt onCreate 这会杀死我的游戏 然后立即从
  • 当手机旋转(方向改变)时如何最好地重新创建标记/折线

    背景 开发一个使用 Android Google Map v2 的本机 Android 应用程序 使用android support v4 app FragmentActivity 在 Android v2 2 上运行 客观的 在更改手机方
  • Android - 将 ImageView 保存到具有全分辨率图像的文件

    我将图像放入 ImageView 中 并实现了多点触控来调整 ImageView 中的图像大小和移动图像 现在我需要将调整大小的图像保存到图像文件中 我已经尝试过 getDrawingCache 但该图像具有 ImageView 的大小 我
  • 保护 APK 中的字符串

    我正在使用 Xamarin 的 Mono for Android 开发一个 Android 应用程序 我目前正在努力使用 Google Play API 添加应用内购买功能 为此 我需要从我的应用程序内向 Google 发送公共许可证密钥
  • 如何将图像从 Android 应用程序上传到网络服务器的特定文件夹中

    如何将图像从 android 移动到 Web 服务器上的指定文件夹 这是我的安卓代码 package com example bitmaptest import java io ByteArrayOutputStream import ja

随机推荐

  • Python-re模块-正则表达式模块常用方法

    re模块介绍 Python的re模块提供了正则表达式的功能 可以用来进行高级的字符串匹配和处理 re模块的主要功能包括 编译正则表达式 使用re compile 可以编译正则表达式字符串 生成正则表达式对象 匹配字符串 使用正则表达式对象的
  • 2021年全国职业院校技能大赛 “大数据技术与应用”—模拟赛题(三)

    2021年全国职业院校技能大赛 大数据技术与应用 模拟赛题 三 文章适合了解大数据技术与应用技能大赛 赛题 文章在编写过程中难免有疏漏和错误 欢迎大佬指出文章的不足之处 更多内容请点进 Lino White 查看 未来的世界充满着各式各样的
  • 数据清洗规则

    数据清洗主要针对四种情况 1 缺失值 2 重复值 3 异常值 4 无用值 1 缺失值处理 重要性高 缺失率低 通过计算来填充 重要性高 缺失率高 可以从其他渠道数据进行补充 或者相关数据进行计算得出 重要性低 缺失率高 不处理或简单填充 重
  • 报错ReferenceError: Cannot access ‘xxxx‘ before initialization解决方案

    ReferenceError Cannot access xxxx before initialization 报这个错的原因其实就是和你声明的变量有关 我们都知道var存在变量提示 但是其实const和let在某种意义上也是存在变量提升的
  • Lua脚本学习

    1 介绍 Lua是一种轻量级的脚本语言 具有以下特点 简单易学 Lua语法简单 易于学习和使用 高效性 Lua的解释器非常快 可以在很短的时间内执行大量的代码 可嵌入性 Lua可以嵌入到其他应用程序中 作为脚本语言使用 可扩展性 Lua可以
  • 每日一题-错误的集合

    错误的集合 题目 示例 解题 题目 集合 s 包含从 1 到 n 的整数 不幸的是 因为数据错误 导致集合里面某一个数字复制了成了集合里面的另外一个数字的值 导致集合 丢失了一个数字 并且 有一个数字重复 给定一个数组 nums 代表了集合
  • Qt之电子时钟

    进一步认识Qt中的属性 我们现在再做一个小练习 去实现一个简易版电子时钟的效果 效果展示 新建项目 我们创建了lcdclock2类 其实是没有用到的 实际上是添加新一个C 文件来实现电子钟 添加C 文件 代码 clock h ifndef
  • 二进制、十进制、八进制、十六进制 各代表的英文字母是什么

    二进制是Binary 简写为B八进制是Octal 简写为O十进制为Decimal 简写为D十六进制为Hexadecimal 简写为H
  • 蓝桥杯第十一届省赛题解(Python)

    第一题 不出意料的签到题 遍历 法一 ans 0 for i in range 1 2021 for j in str i if j 2 ans 1 print ans 法二 s 0 for i in range 1 2021 s str
  • 经典的机器学习方面源代码库

    编程语言 搞实验个人认为当然matlab最灵活了 但是正版很贵 但是更为前途的是python numpy scipy matplotlib 和C C 这样组合既可搞研究 也可搞商业开发 易用性不比matlab差 功能组合更为强大 个人认为
  • IDEA比较两个jar包

    比较两个jar包是否一致 To compare two jar files select them in the Project view and press D 如需比较两个jar包 可以在Project视图里面选中他们 按 common
  • CMake项目使用ctest+gtest进行单元测试

    随着CMake工具越来越强大便捷 越来越多的C C 项目转而使用CMake来进行编译管理 它还提供了用于测试的ctest命令来执行项目中编写的单元测试 本文就以一个实例来介绍如何使用ctest来进行单元测试 一 环境准备 本文实例环境VSC
  • 数据结构与算法-实验1链表的建立与操作

    实验目的 掌握链表数据结构的建立及操作 实验重点 利用链表的原空间进行链表的反转 实验内容 设计一个将输入数据建立成链表 并依次输出链表数据 利用原空间把链表反转的程序 实验步骤 掌握链表的数据结构 建立空链表 用头插法向链表插入数据 实验
  • Ubuntu 操作系统学习笔记之c/c++开发环境配置

    ubuntu下的c c 环境搭建是比较简单 因为有apt和新立得的帮助 1 首先是配置gcc 在ubuntu安装完成已经有gcc了 gcc是由GNU之父Stallman所开发的linux下的编译器 全称为GNU Compiler Colle
  • 操作系统-内存管理习题

    题干 在页式存储管理中 假设作业的地址为16位 页长为4KB 作业的第0 1 2逻辑页分别放在内存的第5 10 11物理块中 试计算作业中逻辑地址2F6AH 0E3CH 526CH 十六进制数 相对应的内存物理地址 说明转换过程 写出转换结
  • 芯片的本质是什么?(2)为什么是半导体材料

    为什么是半导体材料 我们知道 芯片用的是半导体材料 可为什么是半导体呢 一句话概括 因为只有半导体才能 用电控制电 在半导体之前 人类只能用机械控制电 比如 电报的工作原理 是通过滴滴滴哒哒哒的机械开关 控制电流的导通和断开 从而将信息传递
  • SpringBoot文件上传-单文件与多文件上传的使用

    在Spring Boot中 文件上传可以使用MultipartFile来处理 下面将为你演示如何进行单文件和多文件上传 一 单文件上传 1 1 首先 你需要创建一个表单界面来选择和上传单个文件 在HTML中 你可以使用类似于下面的表单
  • IDEA中Spring配置错误:class path resource [.xml] cannot be opened because it does not exist

    如果在运行 Spring 项目时出现了类似于 class path resource applicationContext xml cannot be opened because it does not exist 这样的异常 意思就是没
  • 智慧宿舍系统--宿舍维修管理解决方案

    在大学生活中 宿舍维修是一个必不可少的环节 然而 传统的宿舍维修管理方式通常需要大量的人力和物力投入 效率低下 质量难以保证 为了提高宿舍维修工作的效率和质量 减少人力物力的浪费 现在可以利用物联网 人工智能和数字化平台等技术来实现宿舍维修
  • Cocos2d-x中使用第三方so库

    项目中如果使用到第三方的SDK 大多数是以 so动态共享库的文件打包给我们使用 如何使用他们 见下面分析 1 获得库文件 假如我们得到的库文件是libxxx so 注 关于 so文件的命名方式 可百度 在Jni目录下新建prebuilt文件