UE4安卓Gradle工程中的libUE4.so的生成原理

流程图

流程图放在最前面,下面是讲解。

libUE4.so

问:在UE4安卓开发中,libUE4.so即是符号表,又是引擎代码native,是吗?

答:是的,libUE4.so在UE4安卓开发中既包含符号表,也包含引擎的本地代码。这个库文件是UE4引擎的核心部分,包含了游戏运行所需的所有本地代码和符号信息。

符号表是程序的一部分,用于将程序中的符号(如变量名、函数名等)映射到它们在内存中的地址。在调试和开发过程中,符号表对于理解程序的工作原理和调试程序非常重要。

libUE4.so文件包含了引擎的本地代码,这些代码是游戏运行时执行的核心逻辑。这些代码是用C++编写的,并在编译时被编译成本地代码,以便在Android设备上运行。

因此,libUE4.so文件在UE4安卓开发中非常重要,它包含了游戏运行所需的所有本地代码和符号信息。

问:一个 libUE4.so 解压开来看到是怎么样的?对于UE4安卓构建来说,一个libUE4.so ,它即包含了代码,充当游戏的代码运行库,也包含了调试信息,可以充当符号表,是吗?

答:它解开来如上。是的,对于Unreal Engine 4(UE4)构建的安卓应用来说,`libUE4.so`是一个共享库(shared object),它确实包含了游戏或应用的代码以及可能包含的调试信息。

- **代码**: `libUE4.so`包含了UE4游戏项目的所有编译后的代码。这是游戏运行时所需的代码库,它实现了游戏逻辑、渲染、物理模拟、网络通信等功能。

- **调试信息**: 在开发过程中,如果构建配置设置为包括调试信息(例如,在UE4编辑器中选择"Development"或"Debug"配置),则`libUE4.so`文件还将包含调试符号。这些调试符号允许开发者在调试过程中查看变量值、设置断点、追踪执行流程等。

调试符号通常会增加文件的大小,因为它们包含了额外的元数据,这些元数据映射了机器码和源代码之间的关系。在最终发布版本中,为了减小应用程序包的大小,通常会移除这些调试符号。

在UE4中,你通常有以下几种构建配置选项:

- **Development**: 包括调试符号,但不进行优化,便于调试。

- **Debug**: 包括调试符号,并且可能会进一步降低性能以支持更深入的调试。

- **Shipping**: 不包括调试符号,进行全优化,适用于最终发布的版本。

如果需要在发布版本之后进行调试,开发者可能需要保留一个带有调试符号的特殊构建,以便于在必要时进行分析和调试。在Android平台上,可以通过使用NDK工具(如`ndk-stack`)来解析崩溃报告和`libUE4.so`中的符号信息,从而帮助诊断问题。

Gradle中的libUE4.so

经过BuildAndroid步骤后,而无须等到Package阶段(【MarkA】), Intermediate/Android/gradle 工程中存在 libUE4.so,它的位置是

D:\{项目}\Intermediate\Android\arm64\gradle\app\src\main\jniLibs\arm64-v8a\libUE4.so

D:\{项目}\Intermediate\Android\arm64\jni\arm64-v8a\libUE4.so

以及可以看到:

D:\{项目}\Intermediate\Android\gradle\app\src\main\jniLibs\arm64-v8a\libUE4.so

MarkA处的解释是:打包Android的步骤,即BuildMode.Build(),之中,打开了以下开关,但此文中,这个知识点不是很重要。

if (Makefile.bDeployAfterCompile)
{TargetReceipt Receipt = TargetReceipt.Read(Makefile.ReceiptFile);Log.TraceInformation("Deploying {0} {1} {2}...", Receipt.TargetName, Receipt.Platform, Receipt.Configuration);UEBuildPlatform.GetBuildPlatform(Receipt.Platform).Deploy(Receipt);
}

问:JNI的含义是什么?

答:在安卓开发中,JNI 是 Java Native Interface(Java本地接口)的缩写。

JNI 是一种编程框架,用于在 Java 程序和本地代码(如 C/C++)之间进行交互。它提供了一组标准的接口和机制,使得 Java 程序能够调用本地代码,并且本地代码也能够调用 Java 程序。

使用 JNI,开发者可以在 Java 程序中调用本地代码来执行一些高性能、底层或与特定平台相关的操作。这对于需要与底层系统交互、访问硬件功能或使用现有的本地库的应用程序非常有用。

在安卓开发中,JNI 经常用于以下情况:

1. 访问本地库:通过 JNI,可以将本地库(如 C/C++ 编写的库)与 Java 代码进行绑定,从而在 Java 程序中调用本地库的功能。

2. 调用系统 API:JNI 可以用于调用安卓系统提供的底层 API,以实现与系统功能的交互,如访问传感器、摄像头、文件系统等。

3. 性能优化:JNI 可以用于将一些性能敏感的代码从 Java 转移到本地代码中,以提高执行效率。

使用 JNI 需要编写一些本地代码,并在 Java 代码中进行相应的声明和调用。JNI 提供了一组函数和规范,用于管理 Java 对象和本地数据之间的转换、内存管理、异常处理等。

问:native是什么意思?

答:也就是安卓原生底层代码的意思。

问:NDK是什么意思?

答:NDK是Native Development Kit的缩写,中文通常翻译为“原生开发工具包”。它是由Google为Android平台提供的,允许开发者使用C或C++等本地编程语言编写应用程序的一部分。NDK提供了交叉编译器、工具和库,使得开发者能够编写和编译本地代码,然后将这些代码与Java或Kotlin编写的应用程序集成。

NDK的主要用途包括:

性能优化:对于需要高性能计算的应用,如游戏、图像处理或音频处理,使用NDK可以更直接地访问硬件资源,从而提高性能。

复用现有代码:如果开发者有大量的C或C++代码,他们可以使用NDK将这些代码集成到Android应用程序中,而不需要重写代码。

访问系统级API:NDK允许开发者访问一些Android系统级别的API,这些API可能不会被Java或Kotlin暴露。

开发游戏和图形密集型应用:游戏开发通常需要大量的本地代码来处理图形渲染和物理模拟等任务,NDK提供了必要的工具和库来支持这些操作。

使用NDK进行开发时,开发者需要使用CMake或ndk-build等工具来构建本地代码,并生成可以在Android设备上运行的本地库(如.so文件)。然后,这些本地库可以与Java或Kotlin代码通过JNI(Java Native Interface)或Java API进行交互。

生成原理

下面这张图表示了 libUE4.so 的来龙去脉,它们都是拷贝的关系,实际上是同一个文件。

(图:libUE4.so的拷贝走向图)

接下来是这张图的解释:

BuildAndroid

首先进行 BuildAndroid步骤。“BuildAndroid步骤”的命令如下:

%UBT% %ProjectName%Client Android %TargetBuildConfig% %ClientPath%\%ProjectName%.uproject -NoMutex %PGOProfile% %EXPORT_LINK_MAP% -log=%ClientPath%\%ProjectName%-Build-Android.log

对应日志:

2024-10-31 22:29:12:436 : WARNING: UnrealBuildTools.Commandline = {项目名}Client, Android, Shipping, D:\{项目名}.uproject, -NoMutex, -PGOOptimize

在编译代码的日志中找到 “项目名Client-Android-Shipping-arm64.so”的踪迹,说明它产生于 Execute Actions 中(什么是Execute Actions,可以参考我的文章 UBT如何编译UE4工程代码_ue ubt link-CSDN博客)。它的完整路径是: {项目}\Binaries\Android\{项目名}Client-Android-Shipping-arm64.so

2024-10-31 22:39:10:788 :   16 warnings generated.
2024-10-31 22:39:26:754 :   [37/38] 项目名Client-Android-Shipping-arm64.so
【这里打出来了】2024-10-31 22:39:26:847 :   [38/38] 项目名Client-Android-Shipping.target

“项目名Client-Android-Shipping-arm64.so”就是后来的 libUE4.so,它是Build安卓目标的产物。我在这里花费了很多时间,因为存在增量编译的缘故,它一直存在在本地,导致我在日志中查不到它的来源。因此,在 BuildAndroid 前,先将它删除掉,这样就能得到上面的日志文件了。

四次拷贝

“libUE4.so的拷贝走向图”中的其中两个,对应的是下图中的两个。

具体的拷贝过程在图中可以看出,因此不再详述,下面是整个流程图的完整版:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/58922.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C4.【C++ Cont】C++数据类型和typedef的补充说明

1.数据类型 C同C语言的一样的数据类型不在赘述,参见3.【C语言】内置数据类型,这里只讲不同点 1.在C中,布尔类型包含在头文件iostream中,不用像C语言一样包含stdbool.h 布尔类型变量的定义写法和C语言不同,只能写成 bool a true; bool b false; bool不可写成_Bool或Bool …

Windows部署rabbitmq

本次安装环境: 系统:Windows 11 软件建议版本: erlang OPT 26.0.2rabbitmq 3.12.4 一、下载 1.1 下载erlang 官网下载地址: 1.2 下载rabbitmq 官网下载地址: 建议使用解压版,安装版可能会在安装软件…

前端学习-盒子模型(十八)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 盒子模型组成 边框 语法 边框简写 代码示例 表格的细线边框 语法 内边距 内边距复合写法 外边距 外边距典型应用 外边距合并 清除内外边距 总结 前…

GHuNeRF: Generalizable Human NeRF from a Monocular Video

研究背景 研究问题:这篇文章要解决的问题是学习一个从单目视频中泛化的人类NeRF模型。尽管现有的泛化人类NeRF已经取得了令人印象深刻的成果,但它们需要多视图图像或视频,这在某些情况下可能不可用。此外,一些基于单目视频的人类…

为啥学习数据结构和算法

基础知识就像是一座大楼的地基,它决定了我们的技术高度。而要想快速做出点事情,前提条件一定是基础能力过硬,“内功”要到位。 想要通关大厂面试,千万别让数据结构和算法拖了后腿 我们学任何知识都是为了“用”的,是为…

离线安装Vue2开发环境

在外网进行Vue2开发后,需要转到内网开发,无法在线依赖库安装,需要迁移node_modules。 1.内外网开发电脑安装同样版本的nodejs 我本地安装的node-v16.17.1-x64.msi,所以在内网环境也要按照node-v16.17.1-x64.msi。 在外网环境使用…

初探Flink的序列化

Flink中的序列化应用场景 程序通常使用(至少)两种不同的数据表示形式[2]: 1. 在内存中,数据保存在对象、结构体、列表、数组、哈希表和树等结构中。 2. 将数据写入文件或通过网络发送时,必须将其序列化为字节序列。 从内存中的表示到字节序列…

【ESP32】ESP-IDF开发 | I2C控制器+I2C主从收发例程

1. 简介 I2C(Inter-Integrated Circuit),是由Philips公司在1980年代初开发的一种半双工的同步串行总线,它利用一根时钟线和一根数据线在连接总线的两个器件之间进行信息的传递,为设备之间数据交换提供了一种简单高效的…

提高交换网络可靠性之端口安全配置

转载请注明出处 此实验为配置交换机端口安全,当非法设备接入接口时自动触发安全措施 1.查看PC1和PC2的MAC地址👇 2.交换机改名为S1,同时启用端口安全 3.配置允许接入设备 4.设置违规处理方式:即违规则关闭端口 5.查看安全端口相关…

UE5 第三人称学习之动画 control rig

这个东西和建模软件里有的是一个东西,然后IK就是你动脚,他帮你算出小腿大腿该怎么动,FK就是你自己动了大腿,摆小腿,然后再摆脚 就是给每一根骨骼搞一个控制器,给他一个容易选中和操作更明显的图形作为控制…

宏处理将多个excel文件的指定sheet页合并到一个excel文件中

背景了解:有个同事问我:现在他要处理一千多个文件,每个excel文件都有3个sheet页签,想把所有的excel文件的第二个sheet页签复制一份放到一个新的excel文件中。如果是手动去操作一个个文件的复制,也没什么不可&#xff0…

Linux系列-进程的概念

🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 这篇文章,我们主要分析一下进程。 之前,我们讲过了冯诺依曼体系架构, 我们常见的计算机,像笔记本,或者不常见的计算机…

SQL优化经验大全(表设计优化,索引优化,索引创建规则、索引失效场景,sql语句优化,主从复制,分库分表)面试题

目录 1.表的设计优化 2.索引优化 2.1 索引创建的规则 2.2 索引失效的场景 3.SQL语句优化 4.主从复制、读写分离 5.分库分表 5.1.怎么判断项目是需要分库还是要分表? 5.2 分库分表有哪些拆分方案? 5.2.1 垂直分库 5.2.2 垂直分表 5.2.3 水平分…

css边框修饰

一、设置线条样式 通过 border-style 属性设置,可选择的一些属性如下: dotted:点线 dashed:虚线 solid:实线 double:双实线 效果如下: 二、设置边框线宽度 ① 通过 border-width 整体设置…

OpenGL入门002——顶点着色器和片段着色器

文章目录 一些概念坐标转换阶段顶点着色器片段着色器VBOVAO 实战简介main.cppCMakeLists.txt最终效果 一些概念 坐标转换阶段 概述: 模型空间、世界空间、视图空间和裁剪空间是对象在3D场景中经历的不同坐标变换阶段。每个空间对应渲染管道的一个步骤,…

LeetCode 684.冗余连接:拓扑排序+哈希表(O(n)) 或 并查集(O(nlog n)-O(nα(n)))

【LetMeFly】684.冗余连接:拓扑排序哈希表(O(n)) 或 并查集(O(nlog n)-O(nα(n))) 力扣题目链接:https://leetcode.cn/problems/redundant-connection/ 树可以看成是一个连通且 无环 的 无向 图。 给定往…

C语言指针与一维数组 Java动态初始化与常见问题(越界问题)

1./*int main(void) { int a[5] { 10,20,30,40,50 };//数组间的元素地址相连的 int* p; printf("a代表的地址:%d\n", a);//数组首个元素的地址 printf("a1代表的地址:%d\n", a 1);//偏移数组 printf("a2…

2023年SEO趋势分析与未来发展展望

内容概要 在2023年的数字营销环境中,搜索引擎优化(SEO)依然扮演着关键角色。随着技术的不断演进和用户需求的变化,SEO趋势也在不断变化。首先,核心算法的更新已开始影响网站排名,搜索引擎越来越注重网站内…

面试经典 150 题:189、383

189. 轮转数组 【参考代码】 class Solution { public:void rotate(vector<int>& nums, int k) {int size nums.size();if(1 size){return;}vector<int> temp(size);//k k % size;for(int i0; i<size; i){temp[(i k) % size] nums[i];}nums temp; }…

Linux云计算 |【第五阶段】CLOUD-DAY8

主要内容&#xff1a; 掌握DaemonSet控制器、污点策略&#xff08;NoSchedule、Noexecute&#xff09;、Job / CronJob资源对象、掌握Service服务、服务名解析CluterIP&#xff08;服务名自动发现&#xff09;、&#xff08;Nodeport、Headless&#xff09;、Ingress控制器 一…