Hazel 2024

  1. 不喜欢游戏的人也可以做引擎,比如 cherno

  2. 引擎的作用主要是有两点:

    1. 将数据可视化
    2. 交互
  3. 当然有些引擎的功能也包含有制作数据文件,称之为资产 assets

  4. 不做窗口类的应用栈,可能要花一年才能做一个能实际使用的应用,只需要在游戏引擎中创建一个像 ImGUI 之类的关卡编辑器

    类似于着色编译器

目录

  • 设计
  • 开发
    • 属性配置
    • EntryPoint 入口
    • Logging Library 日志记录
    • premake 构建系统
    • 事件系统
    • 事件系统(下)_实现
      • KeyEvent: 重点
    • 预编译头
  • 技巧
    • Git
    • VS
    • 其他
  • 报错
    • 找不到头文件
    • Sandbox.exe 无法找到入口
    • inconsistent dll linkage 不一致的 dll 链接
    • error LNK2019: 无法解析的外部符号 & fatal error LNK1120: 1 个无法解析的外部命令
    • error LNK2019: 无法解析的外部符号,函数 main 中引用了该符号
    • git push origin main报错 连接不到 443
    • git 拉取超时
    • error C2597: 对非静态成员的非法引用
    • error C2039: "stdout_color_mt": 不是 "spdlog" 的成员
    • error C2040: 间接寻址级别不同
    • 弹窗报错:Sandbox.exe 无法找到入口
    • No Premake script (premake5.lua) found!
    • Error: [string "src/base/api.lua"]:606: bad argument #2 to 'deferredjoin' (string expected, got table)
    • error MSB3191: 无法创建目录,因为同名文件或目录已存在。
    • error MSB3073

设计

  1. EntryPorint:控制了什么,

  2. Apllication Layer
    整个窗口
    处理应用的生命周期和事件,比如运行循环,什么能保持应用运行并渲染帧,什么能够推动时间发展,什么能够执行游戏想要执行的所有代码,什么是事件,窗口调整大小或者关闭,输入事件,鼠标和键盘。需要一种方法来运行游戏或引擎,作为一个实际的应用运行在任意平台

  3. Window Layer
    渲染的目标地,输入事件将来自哪里,整个应用就是这个窗口,和平台支持和渲染接口支持有关

    • 输入
    • 事件:事件管理器
      • 处理输入
      • 广播功能:订阅事件并获得通知
  4. Render

    引擎最重要占比最大的一部分,很多引擎教程都是从渲染器开始。但是自己做一个引擎会从调试器开始,其实当其他部分都完成的时候,渲染器的构建将会变得非常简单

    通常是每帧一次

  5. Render API (OpenGL 是最简单的接口,跨平台)

    最后 Hazel 将会支持多种渲染接口,如 Vulcan(在实现一些东西的时候会比 OpenGL 更高效)

  6. Debugger Support

  7. Scripting Language

    不用一直写 c++

  8. Memory Systems

    内存对于性能而言很重要,比如分配内存的时候CPU的耗时

    自定义分配器和内存跟踪

  9. Entity-Compoennt-System(ECS)
    实体-组件系统,模块化游戏制作过程,能够包含特定的组件

  10. Physics

  11. File I/O, VFS(virtual file system)

  12. Build System

    能够把现有的 3D 模型或者资产自动导入引擎变成优化后的资产格式

    能够在 photoshop 更改后事实热更新到引擎内

开发

  1. 视频是 VS2017,视频中讲到过,但是 github 文档说 VS2019 也可以

  2. git clone https://github.com/xieyouchen/Hazel Git 这一句指令是把 Hazel 项目拷贝到 Git 空文件夹(如果没有创建 Git 空文件夹会自动创建),把里面的所有文件(包括隐藏文件)拷贝到本地的 Hazel 文件夹。

    如果只是 git clone … 那么会在指定位置先创建一个 Hazel 文件夹,再 clone 下 github 内所有资源
    为什么不先 clone 到空文件夹,然后再创建 VS 解决方案?其实是一样的,都需要手动迁移一下文件内容,因为 git clone 克隆下来的文件夹和 vs 创建解决方案时创建的文件夹应该处于同一文件层级

  3. 使用动态链接,将引擎和制作的可执行文件 .exe 动态链接,可以自定义加载或者卸载某些部分,会存在很多依赖项链接到引擎的 engine.dll,再将 engine.dll 链接到游戏

    c++系列有个视频介绍过动态链接和静态链接的区别,以及动态库和静态库,总的来说就是静态库会臃肿

属性配置

cherno 有个视频是在 window 设置 c++ 的视频,建立 c++ VS 项目的最好方式,会介绍配置

  1. 通用 -> 属性管理器 -> 活动解决方案平台,直接把 x86 删掉,因为 32 位的系统很少人用了

  2. 同理把下面的,项目上下文 -> 平台下拉框,把 Win32 删掉

  3. 通用 -> 配置类型,.exe 可执行文件改成 .dll 动态链接文件

  4. 这个 engine.dll 文件将会输出到解决方案目录下的 bin 文件夹,通过文件的类型存储到对应文件夹,文件夹名字为 “Release/Debug - 平台(x64)”,再放到 Hazel 文件夹下面
    在这里插入图片描述

  5. 中间目录就是 VS 创建的所有文件(比如 obj 文件)将会输出到的地方,所以最好还是使用一个区别于输出目录 bin 的文件夹 bin-int,这样你完全可以把 bin-int 给删掉,因为我们自己实现的部分全部在 bin 文件夹

  6. 在解决方案内(注意不是 Hazel )创建一个游戏 Sandbox 使用 Hazel,重复一遍 Hazel 的配置项设置,区别在于 Sandbox 是一个可执行文件 .exe,并设置为启动项目

    这里有个小技巧,当打开某个项目的属性面板时,直接双击别的项目,也会打开该项目的属性面板

  7. 使用 vscode 打开 sln 文件,把 Sandbox 改成第一项,这样别人从 github 克隆下来打开解决方案时,也能以 Sandbox 为启动项目

    本地的启动项目为 Sandbox 被记录在 .vs 文件中,.vs 文件一般不会上传到 github

  8. 给 Sandbox 添加 Hazel 的引用,打开 Sandbox 属性 -> 链接器 -> 命令行 -> Debug 配置,和视频中的不一样,我这里没有 Hazel.lib 文件
    在这里插入图片描述
    但是在解决方案面板中可以看到是有的
    在这里插入图片描述

    这里解释为什么我们设置生成的文件是 .dll,但视频中链接的确是 .lib 文件,因为 VS 编译 dll 文件时,会生成 lib 文件,包含了 dll 中所有函数

  9. 折叠 Hazel 所有的文件,创建我们需要的 src 文件夹,Sandbox 同理。这个显示所有文件的功能好神奇,要么显示 src 文件夹,要么显示初始化的所有文件夹

  10. 这个时候可以看到 bin 路径下已经有了 dll 文件,需要说明的是,实际运行代码的是 dll 文件,lib 文件会被链接到 Sandbox 中,这样就知道有哪些函数可以用以及这些函数在 dll 文件的什么地方
    在这里插入图片描述

  11. Sandbox 中引入命名空间后,执行 Hazel::Print(),编译不会出错,但直接执行会导致 dll 文件缺失,这种问题怎么解决?其实有自动化的方法,也可以直接把 dll 文件复制到 Sandbox.exe 同目录下

EntryPoint 入口

除非是静态链接库,其他都有入口,包括动态链接库

  1. 将析构方法 ~Appliaction() 变为虚函数,因为这个类会被(Sandbox)继承

    1. 支持多态
    2. 确保基类指针创建的派生类对象调用对应的析构函数时,正确释放内存
  2. 因为 __declspec(dllexport) 只在 Win 中被使用,所以定义一个宏限定 Win 使用,这个宏需要在解决方案的配置项内设置:c/c++ -> 预处理器 -> 预处理器定义 HZ_PLATFORM_WINDOWS;HZ_BUILD_DLL。并且需要注意的是,这里应该设置为 Debug 配置时候定义宏, 映射到 __declspec(dllexport),而 Release 没有,映射宏为 __declspec(dllimport)

  3. 为什么 Hazel::CreateApplication() 要在客户端定义,并且定义在类 Sandbox 的外面,而不是直接定义为 public 内?

  4. extern 是怎么找到外部的 Hazel::CreateApplication() 的?这里的 extern 只是告诉该文件后文出现 CreateApplicaiton() 的地方,该函数是外部定义的

  5. 目前 EntryPoint.h 文件中有标红,但是执行成功,这个不用管吗?extern 的作用就是把其后的所有内容在项目中找到相似的实现并引用
    在这里插入图片描述
    很神奇的是,在 EntryPoint.h 的 main 函数测试部分添加 printf(“Hello”) (需要在 Hazel.h 中添加 stdio.h 头文件),执行成功再把测试部分删除后,不标红了

  6. 使用 git 不一定用 git bash,可以直接再资源管理器里面用 cmd

  7. alt + d 是资源管理器的搜索栏快捷键

  8. .gitignore 中 # 表示注释,.vs/ 可以无视 .vs 文件夹,*.user 可以无视 .user 后缀的文件 (.user 无法无视 Hazel.vcxproj.user 文件)

  9. git reset . 退回到上一步

  10. 我的 github 默认主分支是 main,不是 master

  11. git add . 和 git add * 的区别是什么

  12. cherno 用的是 git push origin master,但是我的 github 默认主分支是 main,所以我使用 git push origin main

Logging Library 日志记录

记录所有的信息,比如启动信息,系统的信息,文件是否被打开,着色器是否成功编译,引擎正在做哪些事情
错误是红色,警告是黄色,普通信息是绿色,不重要信息是灰色

重点是格式化数据,比如有时候要打印对象,有时候打印数字,字符串,并且参数可能不定

  1. 使用 git submodule add https://github.com/gabime/spdlog Hazel/vendor/spdlog 将外部依赖库 spdlog 作为子模块导入到主仓库 Hazel/vendor/spdlog 文件夹下,可以保证主仓库和子模块仓库的独立性

  2. 因为 Logging 需要在所有项目中都能使用,所以把 spdlog 第三方依赖的 include 文件夹路径名添加到 “所有配置” 的附加包目录中去
    在这里插入图片描述

  3. 解决方案中左上角显示 “挂起的编辑” 是什么意思
    在这里插入图片描述

  4. inline 什么作用?内联函数,用于降低程序的运行时间,编译期间把函数体复制到函数调用处,减少函数调用时候入栈出栈的开销,适合函数不超过10行 (相比于宏,多了类型检查等好处)

  5. Log.cpp 调用的 s_CoreLogger 和 s_ClientLogger 是 Log.h 文件内的 static 标注的变量吗?是的,在 .cpp 文件相当于声明有这个变量,动态链接库会帮忙链接两个变量 (ctrl + 左键能跳转到 static 位置)

  6. 只是修改了头文件,就不需要更换 dll 文件,那么 dll 文件应该是只包含了 .cpp 文件

premake 构建系统

修改项目操作:

  1. 修改完代码后保存文件
  2. 到工程文件根目录,双击 GenerateProject.bat 脚本
  3. 进入到 VS,会弹窗口,直接全部重新加载
  4. 按 F5 即可正常运行
  1. kind “SharedLib” 表示项目是 dll,在 premake 中,共享库和动态库相同

  2. ** 表示递归搜索文件

  3. cfg: configuration 配置

  4. files 表示要包含的所有的文件列表

  5. include 用于包含头文件,相当于附加包含目录

  6. filter 过滤器,只考虑 windows 的情况,

  7. cppdialect 设置语言版本

  8. staticruntime, 连接运行时库有关,我们希望静态连接

  9. systemVersion win SDK版本

  10. postbuildcommands 从配置中复制构建目标的相对路径

  11. 根据最新的 premake5 的文档修改的代码,两种方式都可以

    -- 编译好后移动Hazel.dll文件到Sandbox文件夹下
    postbuildcommands{("{COPY} %{cfg.buildtarget.relpath} ../bin/".. outputdir .."/Sandbox/")--("{COPY} %{cfg.buildtarget.relpath} \"../bin/".. outputdir .."/Sandbox/\"")
    }
    
  12. 如何运行 premake.lua ?

  13. 从官网下载下来的 premake 文件夹有很多 dll 文件,但是如果删了之后好像也能运行
    在这里插入图片描述
    这样也可以
    在这里插入图片描述

事件系统

  1. 可以处理窗口事件,比如:关闭窗口、调整窗口大小、鼠标键盘输入事件
  2. 如果要做一个渲染器,没有事件系统也没问题。但是对于一个引擎来讲,是可视化创作工具,需要很多设计功能,鼠标键盘就能操作,比如一个可以通过鼠标键盘或其他工具移动的相机。
  3. 自定义事件是立即处理事件,没有缓冲事件
    缓冲事件:键盘 A 一直按,第一个A输出后,停顿一下再一直输出
  4. 事件都是阻塞事件,意味着没有被缓冲,事件没有被延迟。只要发生,比如鼠标被点击,那么整个应用会停止,优先调度(get dispatched)点击事件。

    区别于更加复杂也更优秀的过程:先从事件中获取信息,再推送到某个队列或某个缓冲区,这会产生延迟的现象,直到真正处理该事件。例如像传递、或者通过某事件总线之类的方式传递。

事件系统(下)_实现

目的是让 Application 创建一个窗口 Window,并且 Window 不会知道 Application 的信息,所以 Application 在创建窗口的时候需要创建一个 callback。
https://blog.csdn.net/alexhu2010q/article/details/106942099

  1. 创建一个 Events 文件夹,包含有 Event.h、KeyEvent.h、MouseEvent.h、Application.h 头文件,其中以 Event.h 为主,是整个事件系统的主要文件,其他三个作为不同的事件独立
  2. 需要确定的是事件系统的接口是啥?如果要自己创建一个事件,需要做什么?
  3. 包含的如 standard.h 这样的原生 c++ 文件应该包含在预编译头文件中,甚至于应该包含在 Core.h 文件中
  4. 事件系统是阻塞型事件,前面说过,不像是从事件中获取信息,将其推送到某个队列缓冲区,没有事件总线一样的东西进行传递
  • Event:作为事件的基类,最基本的接口有:获取该事件的类型GetEventType(); 获取该事件的名字 GetName();同时还可以有一个 ToString() 函数方便打印一些消息
  1. EventType: 将事件的类型写成 enum 形式,当需要在运行时候获取到事件的类型名字时,就不用使用 dynamic_cast 之类的函数
  2. EventCategory: 事件的类型 enum 形式用于过滤掉某些事件,比如说:Application 类会接受所有的事件,但是只关心键盘事件或鼠标事件

    EventType 关注的是某个具体的鼠标事件,EventCategory 表示一种类型,某些时候需要所有的鼠标类型表述
    也是一个位字段,BIT(),这个函数是宏定义在 Core.h,#define BIT(x) (1 << x) ,左移1位,相当于 2 x 2^x 2x
    目的:让它不局限于 0 1 2 3 4,因为一个事件可以分成多个分类,比如:键盘、鼠标和鼠标按钮事件都是输入事件 EventCategoryInput,而鼠标按钮事件又是 EventCategoryMouse 事件。创建一个位字段,就可以设置多个位,简单取掩码,看看什么样的分类和事件,或者一个事件属于什么分类
    那为什么 EventType 没有写

  3. m_Handler: 表示这个事件是否被处理,调度事件去处理不同的层时,不想让事件进一步传递。比如:屏幕上有一个按钮,点击了鼠标,鼠标落在按钮的范围内,事件就被处理。这个时候游戏世界并没有收到点击事件,因为按钮已经被处理过了,m_Handler 就是说明按钮是否被处理
  4. IsInCategory() 是非常简单的工具函数,判断事件是否在给定的 EventCategory 中,用于快速过滤某些事件,只需要对实际分类按位于运算,返回这个 bool 值即可
  5. GetName() 暂时设置为空:一般不会去检索一个事件名称
  6. ToString() 只是用于调试,纯虚函数必须实现,默认返回事件的名称,如果要打印更多信息,直接在函数内添加即可

KeyEvent: 重点

  1. KeyPressedEvent(int keycode, int repeatCount) : KeyEvent(keycode), m_repeatCount(repeatCount) {} 这句话里面的 KeyEvent(keycode) 什么意思,是给哪个变量初始化?是不是调用 KeyEvent 构造函数之后,也会生成一个 m_KeyCode 变量
  2. KeyEvent 的构造函数被放在 protected 内,说明其他类不能构造,只有派生类可以
  3. 对于构造函数中的 repeatCount 是有必要的,防止有时候按下一个键,会触发两次按键事件
  4. 宏定义 #define const char* GetName(x) { return #x; },就是将 x 转化为字符串字面量并返回
  5. GetStaticType() 获取静态类型,有需求是在运行时候能够知道是什么类型,那么不想先实例化一个 KeyPressedEvent 之后,再调用 GetEventType(),所以获取类型最好作为静态函数
    1. 在 EventDispatcher 类中使用,作为调度器,需要检查所有的待处理事件,只有当待处理事件满足目标事件类型,才应该放到待执行列表中等待执行
  6. using EventFn = std::function<bool(T&)>; 这句话,function() 的作用是啥
    1. function() 是一个模板类,可调用一切可调用的实体(lambda 函数、函数指针、函数对象等)
    2. 这句话内,EventFn 是一个类型别名,定义了一个 function 对象
    3. function 对象接受以 T& 参数,返回 bool 值的一个函数
    4. 这里的 T 是模板类型
    5. 这里的 function() 能作为一个接口,存储任何返回 bool 值并接受一个 T& 类型引用作为参数的函数。这样调用者就不用关心函数的实现细节,直接调用。
    6. function 在回调机制、事件驱动编程和泛型编程中作用很大
  7. m_Event.m_Handled = func(*(T*)&m_Event); 这句意思是无论 func 是什么函数,只要返回值是 bool,参数是 T& 类型,那么这个函数在此处都会被调用
  8. 更新、渲染、时钟函数都有对应的事件类,可以以事件的形式传播
  9. 重载的输出流符号作用于日志库,能更方便调用事件的 ToString(),记录事件
  10. HZ_TRACE(e); Application.cpp 文件中运行这句话,因为已经重载过了输出流符号
  11. 必须添加头文件 #include "spdlog/fmt/ostr.h" spd 的输出流操作符,这样就可以自定义输出类型

预编译头

就是一个头文件,源文件添加后可以避免某些头文件被反复编译

  1. hapch.cpp 本来是不需要的,但是 VS 会自动生成
  2. 在 premake.lua 中添加 pchheader “hzpch.h” 和 pchsource “Hazel/src/hzpch.cpp”,后者只有 VS 需要,其他 IDE 会无视。其中,前面那句效果相当于把所有包含了 hzpch.h 的文件属性中预编译头设置为 “使用”,而后面那句效果相当于把 hzpch.cpp 文件属性中的预编译头设置为 “创建”
  3. 再次 Build 工程后,项目配置会提醒是否使用 pch
  4. 之后再所有的 .cpp 文件中包含 hzpch.h (实际上没有使用的 cpp 文件也需要添加)
  5. 需要有一个 hzpch.cpp 文件,告诉编译器把 hzpch.h 预编译头文件的内容全部编译完 (因为 VS 的编译系统以一个个文件为单位,当一个文件发生修改,那么所有文件都会被重新编译,所以把一些不太变动的文件放在预编译头文件中,告诉编译器提前编译好,之后就不会改变,提升编译效率)

技巧

Git

  1. 使用 git 不一定用 git bash,可以直接再资源管理器里面用 cmd
  2. alt + d 是资源管理器的搜索栏快捷键
  3. .gitignore 中 # 表示注释,.vs/ 可以无视 .vs 文件夹,*.user 可以无视 .user 后缀的文件 (.user 无法无视 Hazel.vcxproj.user 文件)
  4. git reset . 退回到上一步
  5. 我的 github 默认主分支是 main,不是 master
  6. git add . 和 git add * 的区别是什么? git add . 会忽略 .gitignore 的文件,但是 git add * 不会
  7. cherno 用的是 git push origin master,但是我的 github 默认主分支是 main,所以我使用 git push origin main
  8. 如何回退到上一版本:git reset --hard HEAD^
  9. 撤回回退:git reflog 查看历史命令,要回退到哪个版本
    git reset --hard 版本号
  10. 撤回 commit 和 add .: git reset (--mixed) HEAD^,括号里的可有可无
  11. 撤销 git add . :git reset . 即可
  12. github 上的版本如何回滚,网页版是没有回滚操作的,只有 Github For Win 客户端有,如果想在网页端操作,可以先按照这个教程 https://blog.csdn.net/weixin_44259720/article/details/112608864 创建一个新的分支,之后把默认分支换成新的分支,同时改名成功,并且把不想要的分支都删掉。这种操作可以在新分支的 Activity 中见到操作记录,但已经是比较好的解决方案。
  13. 所以必须在 push to github 之前查阅将会出现的变化,仔细核对,否则推送到 github 后非常麻烦。或者可以fetch到一个地方之后,再推送到 main 版本
  14. 需要知道 push 哪些文件,是必须的,哪些文件不是必须的,尽量保证 github 仓库中文件的干净程度?可以新建一个分支,先推送试试,如果clone下来发现无法正常运行,可以再尝试?
  15. 首先 bin/ 和 bin-int/ 是编译的结果,可以不 push 到 github;.sln 文件也不需要;.vcxproj 等文件也不需要
  16. .gitignore 只能忽视原来没有被跟踪的文件,如果要解除跟踪,使用 git rm --cached <file>。比如这里需要 git rm --cached *.sln这样能把 .sln 文件给解除跟踪
  17. 提交规范
    feat: 新功能、新特性
    fix: 修改 bug
    perf: 更改代码,以提高性能(在不影响代码内部行为的前提下,对程序性能进行优化)
    refactor: 代码重构(重构,在不影响代码内部行为、功能下的代码修改)
    docs: 文档修改
    style: 代码格式修改, 注意不是 css 修改(例如分号修改)
    test: 测试用例新增、修改
    build: 影响项目构建或依赖项修改

VS

  1. alt + 鼠标左键,竖向选中代码,用于删除代码,或者统一缩进

其他

  1. alt+d 文件资源管理器中快捷定位到路径栏,cmd 可以打开 cmd 窗口

报错

找不到头文件

为什么引用头文件说找不到?改成双引号就行 “Test.h”
在这里插入图片描述
第二种方法,想要引用头文件可以用尖括号 <>,可以进入属性配置面板:c/c++ -> 常规 -> 附加包含目录输入 $(SolutionDir)Hazel\src

<> 头文件会去系统目录寻找,“” 先找项目目录,再找系统目录

Sandbox.exe 无法找到入口

因为 dll 文件没有更新,去把最新的 dll 文件更新下就行,最新的 dll 文件需要看引擎的 dll 文件输出到哪里,从配置属性"常规"里面可以看到
在这里插入图片描述

报错窗口乱码怎么解决,同时报错的窗口英文字母也是乱码怎么解决

inconsistent dll linkage 不一致的 dll 链接

可能是 dll 链接拼写错误
“配置属性面板 -> c/c++ -> 预处理器”
看看里面的宏有没有拼写错误导致 dll 链接失败

error LNK2019: 无法解析的外部符号 & fatal error LNK1120: 1 个无法解析的外部命令

SandboxApp.obj : error LNK2019: 无法解析的外部符号 "class Hazel::Application * __cdecl Hazel::CreateApplication(void)" (?CreateApplication@Hazel@@YAPEAVApplication@1@XZ),函数 main 中引用了该符号
这里是 main 函数中引用的外部引用 extern CreateApplication() 无法解析
extern Hazel::Application* Hazel::CreateApplication();
查看实现 CreateApplication 的文件 Sandbox.cpp 中,发现未添加命名空间
在这里插入图片描述
改为 Hazel::Application* Hazel::CreateApplication() 即可

error LNK2019: 无法解析的外部符号,函数 main 中引用了该符号

error LNK2019: 无法解析的外部符号 "public: static void __cdecl Hazel::Log::Init(void)" (?Init@Log@Hazel@@SAXXZ),函数 main 中引用了该符号
这里仍然是 main 函数内的链接问题,这里的 Hazel::Log::Init() 函数识别不到

  1. 检查 Log 类定义的时候是否添加命名空间
  2. 检查 Log 定义的时候有没有添加 __declspec(dllexport),必须添加字段表示将类导入 dll
    在这里插入图片描述
    我犯了第二个错误
    更改为 class HAZEL_API Log 即可(宏 HAZEL_API 在我的工程中被映射为 __declspec(dllexport))

git push origin main报错 连接不到 443

Failed to connec t to github.com port 443 after 21083 ms: Couldn't connect to server
首先看下 clash pro 的请求日志 Logs,发现都能正常访问
于是重新 git push,弹出窗口要验证码,选择网页验证,输入身份验证器中的号码即可
在这里插入图片描述

git 拉取超时

git submodule add 拉取超时
因为拉取的包太大了
有两种错误提示

  • error: RPC failed; curl 18 HTTP/2 stream 5 was reset09.00 KiB/s
  • fetch-pack: unexpected disconnect while reading sideband packet

把命令改成
git submodule add --depth 1 https://github.com/gabime/spdlog Hazel/vendor/spdlog 添加关键字 ‘–depth 1’,表示只拉取最新一次更新

error C2597: 对非静态成员的非法引用

error C2597: 对非静态成员“Hazel::Log::s_CoreLogger”的非法引用
那就是说明 s_CoreLogger 是非静态成员,但是用成了静态成员,比如说 static 函数的返回值是 s_CoreLogger&,那么就出现错误,static 函数必须返回 static 成员
在这里插入图片描述

error C2039: “stdout_color_mt”: 不是 “spdlog” 的成员

spdlog::stdout_color_mt 这么些报错
是因为没有包含定义 stdout_color_mt 的头文件,这个头文件定义 stdout_color_mt 应该也是定义在 spdlog 这个命名空间内

error C2040: 间接寻址级别不同

error C2040: “s_CoreLogger”:“std::shared_ptr<spdlog::logger>”与“std::shared_ptr<spdlog::logger> &”的间接寻址级别不同
在 Log.cpp 中声明了 Log.h 的变量,但是没有保持两个变量相同内容,.h 中是引用,.cpp 中是变量

这里不要被 .h 文件上面的 public 函数误导,那是公开给别的对象的函数,返回的是引用
在这里插入图片描述
在这里插入图片描述

弹窗报错:Sandbox.exe 无法找到入口

无法定位程序输入点 Hazel::Log::Init() ,在动态链接库上
还是 dll 链接的问题,我这里是没有更新 dll 文件
在这里插入图片描述

No Premake script (premake5.lua) found!

必须命名 premake 文件为 premake5.lua
注意把当前 vs 打开的 premake.lua 文件关闭,重命名之后再打开,否则在 vs 修改的记录按 ctr + s 后,vs 会保存一个 premake.lua 文件到原位置,premake5.lua 的内容不会改变

Error: [string “src/base/api.lua”]:606: bad argument #2 to ‘deferredjoin’ (string expected, got table)

https://github.com/premake/premake-core/issues/1858

error MSB3191: 无法创建目录,因为同名文件或目录已存在。

error MSB3191: 无法创建目录“..\bin\Debug-windows-x86_64\Sandbox\”。无法创建“D:\Projects\Hazel\Hazel\bin\Debug-windows-x86_64\Sandbox”,因为同名文件或目录已存在。
把 {COPY} 改成 {COPYFILE} 不知道为啥报错

-- 编译好后移动Hazel.dll文件到Sandbox文件夹下
postbuildcommands{("{COPYFILE} %{cfg.buildtarget.relpath} ../bin/" .. outputdir .. "/Sandbox")
}

在这里插入图片描述
https://github.com/TheCherno/Hazel/issues/623
复制这个答主的就好了,真他妈高血压

error MSB3073

error MSB3073: 命令“IF EXIST ..\bin\Debug-windows-x86_64\Hazel\Hazel.dll\ (xcopy /Q /E /Y /I ..\bin\Debug-windows-x86_64\Hazel\Hazel.dll ..\bin\Debug-windows-x86_64\Sandbox > nul) ELSE (xcopy /Q /Y /I ..\bin\Debug-windows-x86_64\Hazel\Hazel.dll ..\bin\Debug-windows-x86_64\Sandbox > nul)
再点一次 F5 就可以了

把 Hazel 的 dll 文件复制到 Sandbox 里面发现可以,其实就是一开始检测目录发现是空文件,如果再按一次 F5 再次运行时候,就能检测到存在的文件
https://github.com/TheCherno/Hazel/issues/9

error MSB3073: 命令“copy /B /Y ..\bin\Debug-windows-x86_64\Hazel\Hazel.dll "\bin\Debug-windows-x86_64\Sandbox"
继续报错,不是引号的问题,如果在 cmd 中是可以复制成功的
现在我想知道,执行 copy 的这条语句是在哪里

error MSB3073: 命令“copy /B /Y "..\..\bin\Debug-windows-x86_64\Hazel\Hazel.dll" "..\..\bin\Debug-windows-x86_64\Sandbox\"
退回两层去找 bin,可能是 Hazel/src,但如果是这里,这句命令可以执行成功(cmd 中可以)

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

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

相关文章

VSCode扩展连接虚拟机MySQL数据库

在虚拟机安装MySQL vscode通过ssh远程登录Ubuntu 在vscode终端运行以下命令。 sudo apt-get install mysql-server-5.7 用以下命令确认MySQL是否安装完成。 sudo mysql MySQL安装成功。 在VSCode安装SQL扩展 扩展名&#xff1a;MySQL Shell for VS Code。 安装完成后&am…

JavaScript高级——闭包的作用

1、使用函数内部的变量在函数执行完后&#xff0c;仍然存活在内存中&#xff08;延长了局部变量的生命周期&#xff09; 2、让函数外部可以操作&#xff08;读写&#xff09;到函数内部的数据&#xff08;变量/函数&#xff09; 3、函数执行完后&#xff0c;函数内部声明的局…

使用原生HTML的drag实现元素的拖拽

HTML 拖放&#xff08;Drag and Drop&#xff09;接口使应用程序能够在浏览器中使用拖放功能。例如&#xff0c;用户可使用鼠标选择可拖拽&#xff08;draggable&#xff09;元素&#xff0c;将元素拖拽到可放置&#xff08;droppable&#xff09;元素&#xff0c;并释放鼠标按…

java进销存系统源码:管店云进销存解决方案

在当今数字化转型的大背景下&#xff0c;企业对高效、可靠的进销存管理系统的需求日益增长。Java作为一种广泛使用的编程语言&#xff0c;以其成熟的技术栈和强大的生态系统&#xff0c;成为了开发高性能进销存系统的首选语言之一。本文将介绍一款基于Java进销存系统源码的“管…

c++刷题

17.电话号码的组合 来源于题解思路&#xff1a; 继承 CC14 KiKi设计类继承 #include <iostream> #include <memory> using namespace std; class Shape{ private:int x;int y; };class Rectangle:public Shape { public:Rectangle(int length,int width):Shape…

Cartographer源码理解

一、前言 最近一个半月&#xff0c;利用空余时间对Cartographer源码进行了简单的阅读&#xff0c;在这里做了个简单梳理&#xff0c;和大家分享交流。 cartographer源码量其实是有点大的&#xff0c;逐行逐句去解释实在是有心无力了&#xff0c;而且已经有大佬做了类似的事情…

Java笔试面试题AI答之单元测试JUnit(5)

文章目录 25. 简述什么是Junit 忽略测试&#xff08;Ignore Test&#xff09;&#xff1f;一、基本概念二、使用方法三、注意事项四、示例 26. 简述什么是Junit 超时测试&#xff08;Timeout Test&#xff09;&#xff1f;Junit 超时测试的主要特点包括&#xff1a;实现方式&am…

buildroot移植qt报错Info: creating stash file (补充qt添加字库)

移植qt库&#xff0c;编译文件报错Info: creating stash file /home/rbing/QT/uart/.qmake.stash Project ERROR: Unknown module(s) in QT: serialport rbingouc:~/QT/uart$ /home/rbing/linux/tool/buildroot-2022.02.9/output/host/usr/bin/qmake Info: creating stash fil…

一些写leetcode的笔记

标准库中的string类没有实现像C#和Java中string类的split函数&#xff0c;所以想要分割字符串的时候需要我们自己手动实现。但是有了stringstream类就可以很容易的实现&#xff0c;stringstream默认遇到空格、tab、回车换行会停止字节流输出。 #include <sstream> #incl…

部分动态铜皮的孤岛无法删除。报错

(SPMHCI-1): Cannot break shape into fragments. 网上寻找了很多答案&#xff0c;都不太理想&#xff0c;不是我想要的方法。 终于功夫不负有心人&#xff0c;在Cadence官方论坛找到了蛛丝马迹。 Breaking Static shape into fragments - PCB Design - PCB Design & IC …

uniapp 做一个查看图片的组件,图片可缩放移动

因为是手机端&#xff0c;所以需要触摸可移动&#xff0c;双指放大缩小。 首先在components里建个组件 查看图片使用 uni-popup 弹窗 要注意 transform的translate和scale属性在同一标签上不会一起生效 移动就根据触摸效果进行偏移图片 缩放就根据双指距离的变大变小进行缩…

【 html+css 绚丽Loading 】 000052 璇玑转轮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f…

[网络]http的简单认识

文章目录 一. 什么是http二. http协议工作过程三. http协议格式1. 抓包工具fiddler2. http请求报文3. http响应报文 一. 什么是http HTTP (全称为 “超⽂本传输协议”) 是⼀种应⽤⾮常⼴泛的 应⽤层协议 HTTP 诞⽣与1991年. ⽬前已经发展为最主流使⽤的⼀种应⽤层协议 HTTP 往…

MyBatis中多对一关系的三种处理方法

目录 MyBatis中多对一关系的三种处理方法 1.通过级联属性赋值 1&#xff09;mapper 2&#xff09;mapper.xml 3&#xff09;测试代码 4&#xff09;测试结果 2.通过标签 1&#xff09;mapper 2&#xff09;mapper.xml 3&#xff09;测试代码 4&#xff09;测试结果 3.分步查询 …

【C++二叉树】102.二叉树的层序遍历

107. 二叉树的层序遍历 II - 力扣&#xff08;LeetCode&#xff09; 思路分析&#xff1a; 层序遍历&#xff0c;但是要注意输出的结果是一个二维数组&#xff0c;不是一层一个值一个值的输出&#xff0c;而是要一层一层的输出。可以通过一个循环控制每一层的数据个数&#xff…

PyCharm 安装教程

传送门 PyCharm 是一款由 JetBrains 开发的强大的 Python 集成开发环境&#xff08;IDE&#xff09;。它支持多种功能&#xff0c;包括调试、代码补全、智能代码分析、版本控制集成等&#xff0c;特别适合开发 Python 项目。接下来&#xff0c;我们将详细介绍如何在不同操作系…

【C++高阶】解锁C++的深层魅力——探索特殊类的奥秘

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;C 类型转换 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀C特殊类 &#x1f4d2;1. 不能被拷贝…

文字loading加载

效果 1. 导入库 import sys from PyQt5.QtCore import QTimer, Qt, QThread, pyqtSignal from PyQt5.QtGui import QPainter, QFont, QColor, QBrush from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QProgressBar, QLabel 代码首先导入了P…

C++ | Leetcode C++题解之第409题最长回文串

题目&#xff1a; 题解&#xff1a; class Solution { public:int longestPalindrome(string s) {unordered_map<char, int> count;int ans 0;for (char c : s)count[c];for (auto p : count) {int v p.second;ans v / 2 * 2;if (v % 2 1 and ans % 2 0)ans;}retur…

【设计模式-外观】

这里写自定义目录标题 定义UML图角色作用代码使用场景 定义 为子系统中一组相关接口提供一致界面&#xff0c;定义一个高级接口&#xff0c;使得子系统更加容易使用。 UML图 角色作用 外观&#xff08;Facade&#xff09;角色&#xff1a;这是外观模式的核心&#xff0c;它知…