zoukankan      html  css  js  c++  java
  • UE4 Modules 和 PCH


    本文参考:

    https://zhuanlan.zhihu.com/p/107270501

    https://docs.google.com/presentation/d/1rSFFQk7RxNAHevROfVvUNviUfIntLkO_HpdvzHLkNEs/view#slide=id.g6e0e4b3bcf_2_326

    UE4模块的加载方式

    待补充

    Modules

    模块是什么?一堆dll 类的集合,UE4被分为了1000个模块

    有什么作用?组织代码,可移植性复用性,可以获得更快的编译和链接性能,也可以确认模块何时加载

    如何做一个Module? B U I L D

    Build

    Build,建立一个固定的目录

    [YourModuleName].Build.cs文件的作用用

    描述如何编译模块、模块的依赖等等

    模块的编译只取决于.Target.cs和.Build.cs而不取决于sln

    一个最少代码的模块包括:

    和模块名相同的C#类

    构造函数中处理模块的依赖性,必须依赖Core,里面包括了很多模块相关代码

    Use

    use 使用模块

    模块的代码并不是默认对其他的模块暴露的

    你需要队每个函数或者类进行显式的指定他是否导出

    如果你不打算暴露任何代码到模块外,你可以不用分private和public的文件夹

    这些代码在蓝图中可以访问,但是在其他模块中不能使用

    通过给UCLASS添加MinimalAPI(最小)标识来表示将其显式导出到可以被其他模块使用

    要将某个函数暴露给其他模块使用必须在函数前添加[YourModuleName]_API,全部大写字母

    要将整个类暴露就在类前加[YourModuleName]_API,全部大写字母,这样整个类的public部分都会暴露

    由于这个类依赖了Actor类,所以我们在模块的编译时候会报错

    要用的话,就需要添加头文件、添加模块依赖关系

    这里在publicDependency进行一个添加,因为其他的模块要是引用这个NickNameActor他自然也会需要对Actor有依赖

    关于private 和 public dependency的问题:

    当这个关系只有一层时没有任何区别

    当涉及到三个模块时,这里的依赖的public private就会起作用

    头文件内容传递,表示这个模块可以调用其他模块全部定义在在头文件中的内容,如果有内容是 .cpp中定义,则会有无法解析的外部符号错误(就是将头文件一起编译,但是不会做链接,对应IncludePathModuleNames,现在基本已经弃用了)

    把定义写在头文件中意味着他可能会被多次编译,将拖慢编译速度

    DependencyModuleNames,则是将两个模块链接,则表示这个模块可以调用到.cpp中定义的内容

    private会切断头文件路径链接的传递,你的模块被其他的模块依赖时这些引入的头的链接都不会传递

    非常重要的依赖传递图

    img

    当你的模块被其他的模块引用的时候,情况很多,上图基本包括了所有情况

    你private 引用了别的module,引用了你module的module尝试找你的子模块的代码的时候就会出现文件找不到的错误

    总结选择:建议使用private链接,他们会减少编译时间!

    Implement

    Implement,实现模块

    #include "Modules/ModuleManager.h" // which is in core module
    
    
    IMPLEMENT_MODULE(FPlatformCommonModule, PlatformCommon)
    

    这句话可以在你的模块的任何地方写,这句调用就是将你的模块的主类给暴露给引擎

    实现这个模块的类必须继承这个IModuleInterface的接口,一般来说做个空类就好了可以使用UE自带FDefaultModuleImpl类

    有关module的接口有很多,最基本的就加载和卸载module的生命周期

    有关很少会用到的GameplayModule,游戏工程本身也是一个模块,一般所有的模块都是用给这个游戏模块的,很少会反过来依赖游戏模块

    Load

    LoadModule

    需要选择自己的module是在什么时候被加载的和面向什么target,通过选择Type,最常用的是Runtime和Editor

    Depend

    depend

    只有在依赖链上的模块才会被编译

    通过添加DependencyModuleNames来配置依赖,如果没有模块依赖你的模块,也可以添加Target.cs

    PCH

    Prcompiled Header

    一般的头文件不会自己编译,而是在cpp引入的时候编译

    这样的话就有一个很大的头文件重复编译量

    让头文件只编译一次

    PCH定义了一个头文件,包含了所有最常用的头文件,然后他们会先于所有的文件编译,他们不会重编,除非他们引入的头文件发生了改变

    必须注意的是,如果PCH重编了,所有的这个模块的CPP文件都会重编,最好是用于引擎的头文件或者非常少改动的头文件

    有几种PCH,

    private PCH

    构建你模块自己的PCH,把他定义在Build.cs文件里

    不应该在任何头文件或者CPP文件中引入PCH文件,他们会由UBT工具自动注入到你的模块里

    PCH是一种优化层面的东西

    你的代码写法应该是就算PCH关掉了也能正常跑

    shared PCH

    除了自己定义PCH之外也可使用别人定义的PCH,模块自己定义的SharePCH不能给自己用,只能给依赖了这个模块的模块使用

    只有引擎模块才能创建Share PCH

    Private PCH 和 Shared PCH又是什么?有啥用?

    答:它俩是特殊一点的PCH,只需记住几(×)1(√)点,

    Private PCH是给本模块用的PCH,Shared PCH是给依赖本模块的模块用的PCH
    一个模块可以使用其他模块定义的Shared PCH
    一个模块不能使用自己定义的Shared PCH
    模块对PCH的选择只有三个:
    -使用本模块定义的Private PCH
    -使用引擎自动从**本模块依赖的模块**定义的Shared PCH中,选出一个最佳PCH
    -不使用PCH
    

    两者需要在模块的build.cs文件中手动指定

    UE会自动选择最佳的SharePCH以便尽可能多的覆盖本模块用到的头文件

    Shared PCH的选择范围是本模块依赖的模块中定义的Shared PCH
    
    假如模块A依赖Slate,Core以及CoreUOject模块,且没定义Private PCH,
    且只有Slate及Core模块中定义了Shared PCH,
    那么,A的Shared PCH就只能从Slate, Core两个模块中选
    选哪一个呢?
    
    基于得分来选择——以它俩依赖的<定义了Shared PCH的>模块数量来作为它们的分数
    
    假设Core模块依赖了TraceLog, Json,假如只有TraceLog模块中定义了Shared PCH,
    那么它得1分
    
    假设Slate模块依赖了Core, SourceControl, Json模块,假如Json模块中定义了Shared PCH,
    那么它得2分(Core 1 + Json 1)
    
    而且很容易看出,由于Slate的依赖项里包含了Core,那么它Shared PCH很可能包含了大部分Core模块里的头文件,以及其它额外的头文件,这样,我们就会理所当然的选择使用Slate的Shared PCH,因为我们的模块使用到的头文件,也在Slate的Shared PCH里的概率更大。
    
    因此我们将会选择Slate模块的Shared PCH作为本模块的PCH。
    

    PCH使用模式只选择UseExplicitOrSharePCHs,这个模式下,你没设置PCH就会使用引擎PCH,你设置了PrivatePCH就可以使用

  • 相关阅读:
    Lync二次开发
    Socket 一对多通信
    DBImport V3.1 数据互导工具及文档生成器更新发布
    Sql学习第六天——SQL 巩固练习(用到了前几天几个知识点)
    文件监控
    Google Protocol Buffers 入门
    [原]常用Linux命令总结[Thx for commandlinefu]
    清理SQL Server日志释放文件空间
    ASP.NET MVC动态二级域名及ASP.NET管道机制
    搜索引擎——JobSearch简介
  • 原文地址:https://www.cnblogs.com/FlyingZiming/p/15017445.html
Copyright © 2011-2022 走看看