Hazel 2024

news2024/11/18 2:36:36
  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.coloradmin.cn/o/2136680.html

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

相关文章

Axure RP 11 Beta 测试版 发布了,目前是免费试用阶段

Axure RP 11 Beta 已经发布上线了&#xff01;各位产品同学可以从下面的链接下载测试版&#xff0c;体验新功能。目前RP11处于免费试用阶段&#xff0c;没有授权的用户也可以免费使用试用版。 与 Axure RP 的以往版本一样&#xff0c;在 RP11 中保存文件后&#xff0c;无法在低…

redis有序集合写入和求交集的速度

背景 团队小伙伴做了一个需求。大概的需求是有很多的图片作品&#xff0c;图片作品有一些类别&#xff0c;每个人进入到每个类别的作品业&#xff0c;根据权重优先查看权重最高的的作品&#xff0c;权重大概是基于每个人对该作品的浏览计算&#xff0c;浏览过的作品放在最后展…

IDEA 通义灵码 插件使用体验

目录 前言 主要功能 演示代码 解释代码 生成单元测试 生成代码注释 生成优化建议 代码片段补全 总结 前言 自从 AI 技术开始大规模应用&#xff0c;老板就想让下面的牛马借助 AI 工具来提高编码效率&#xff0c;由于团队都没有在实际编码中深度使用过 AI 工具&#x…

消息中间件有哪些常见类型

消息中间件根据其设计理念和用途&#xff0c;可以大致分为以下几种常见类型&#xff1a; 点对点消息队列&#xff08;Point-to-Point Messaging Queues&#xff09;&#xff1a; 在这种模型中&#xff0c;消息被发送到特定的队列中&#xff0c;消费者从队列中取出并处理消息。队…

【LeetCode每日一题】——LCR 078.合并 K 个升序链表

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目注意】六【题目示例】七【题目提示】八【解题思路】九【时间频度】十【代码实现】十一【提交结果】 一【题目类别】 优先队列 二【题目难度】 困难 三【题目编号】 LCR 078.合并 K 个升序链表 …

Linux入门——“Linux基本指令”上

在刚开始学习Linux时&#xff0c;首先需要掌握一些基本指令&#xff0c;以便我们能更好地使用Linux操作系统&#xff0c;以下指令在Ubuntu 22上执行。以下内容不过多介绍选项内容。 1.ls指令 ls指令用来查看当前目录下的文件&#xff0c;显示的信息是很有限的一般只显示文件名&…

二进制部署ETCD单机版

文章目录 一、签发etcd证书二、搭建etcd单机版三、测试ETCD服务 一、签发etcd证书 注意&#xff1a;在操作签发证书操作时一定要检查服务器时间、时区是否一致&#xff0c;会导致证书不可用&#xff01;&#xff01; 1、创建etcd目录 mkdir /etc/etcd/{ssl,data} -p2、安装签…

【vue-media-upload】一个好用的上传图片的组件,注意事项

一、问题 media 的saved 数组中的图片使用的是location 相对路径&#xff0c;但是我的业务需要直接根据图片链接展示图片&#xff0c;而且用的也不是location 相关源代码 <div v-for"(image, index) in savedMedia" :key"index" class"mu-image-…

基于SpringBoot的社区宠物管理与推荐系统的设计与实现

文未可获取一份本项目的java源码和数据库参考。 1.课题的基本内容&#xff0c;可能遇到的困难&#xff0c;提出解决问题的方法和措施 2.1课题的基本内容 本课题主要研究基于SpringBoot的社区宠物管理与推荐系统的设计与实现。用户注册登录系统前端后可以可以实现对宠物信息的…

【读书笔记-《30天自制操作系统》-20】Day21

本篇的内容主要是操作系统的保护&#xff0c;涉及到x86 CPU的一些机制&#xff0c;以及操作系统的异常处理。 1. 字符显示API问题解决 首先来解决一下上一篇内容中字符串显示API没有生效的问题。 void hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ec…

为什么H.266未能普及?EasyCVR视频编码技术如何填补市场空白

H.266&#xff0c;也被称为Versatile Video Coding&#xff08;VVC&#xff09;&#xff0c;是近年来由MPEG&#xff08;Moving Picture Experts Group&#xff09;和ITU&#xff08;International Telecommunication Union&#xff09;联合开发并发布的新一代国际视频编码标准…

[每周一更]-(第114期):介绍GitLab不同角色对应的权限

文章目录 GitLab 角色及其权限项目级别角色组级别角色 使用场景示例 工作中一直使用Gitlab搭建了公司内网的代码管理工具&#xff0c;但是不同的用户会分配相应的权限&#xff0c;来管理不同用户及角色的权限信息&#xff0c;我们来介绍下角色的信息&#xff0c;方便我们管理公…

演示:基于WPF的自绘的中国地铁轨道控件

一、目的&#xff1a;演示一个基于WPF的自绘的中国地铁轨道控件 二、效果演示 北京地铁 成都地铁 上海地铁 深圳地铁 南京地铁 长春地铁 哈尔滨地铁 武汉地铁 厦门地铁 香港地铁 三、功能 支持平移、缩放等操作 鼠标悬停显示线路信息和站点信息 按表格显示&#xff0c;按纸张…

传知代码-融合经典与创新的图像分类新途径

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 概述 在当前的深度学习领域&#xff0c;构建兼具高性能与灵活性的卷积神经网络&#xff08;CNN&#xff09;已成为计算机视觉研究的核心课题。本文介绍了一种全新的卷积神经网络架构&#xff0c;该网络巧妙地结合…

MacOS Sonoma(14.x) 大写模式或中文输入法下的英文模式,光标下方永远会出现的CapsLock箭头Icon的去除办法

如图&#xff0c;MacOS Sonoma(14.x) 大写模式或中文输入法下的英文模式下&#xff0c;光标下方永远会出现一个CapsLock箭头Icon。此Icon挡住视野&#xff0c;还容易误触导致切换大小写状态&#xff0c;带来的收益远远小于带来的困扰。 解决办法 打开终端&#xff0c;输入以下…

Go协程及并发锁应用指南

概念 协程&#xff08;Goroutine&#xff09;是Go语言独有的并发体&#xff0c;是一种轻量级的线程&#xff0c;也被称为用户态线程。相对于传统的多线程编程&#xff0c;协程的优点在于更加轻量级&#xff0c;占用系统资源更少&#xff0c;切换上下文的速度更快&#xff0c;不…

Vue:使用v-model绑定的textarea在光标处插入指定文本

一、问题描述 使用v-model绑定的textarea如果需要改变其内容&#xff0c;一般只要改变v-model对应的变量即可&#xff0c;但如果需要在textarea的当前光标位置插入指定文本&#xff0c;那就需要操作DOM了。于是我们写了一段js&#xff1a; const insertTextAtCursor (text) …

聊天组件 Vue3-beautiful-chat

前言 最近很多公司都在搞大模型&#xff0c;类似于 chatgpt 的功能&#xff1b;而 chatgpt 的界面其实就是个对话框。今天就介绍一个不错的对话框组件 Vue3-beautiful-chat 项目框架 vite vue3 TS Vue3-beautiful-chat 使用流程 1、引用三方件 npm install Vue3-beaut…

【大模型专栏—进阶篇】语言模型创新大总结——“三派纷争”

大模型专栏介绍 &#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;本文为大模型专栏子篇&#xff0c;大模型专栏将持续更新&#xff0c;主要讲解大模型从入门到实战打怪升级。如有兴趣&#xff0c;欢迎您的阅读。 &#x1f4…

ChatGPT对话训练数据采集渠道有哪些

ChatGPT是人工智能技术驱动的自然语言处理工具&#xff0c;它可以生成逼真的自然语言回复&#xff0c;被广泛应用于聊天机器人、智能助理等领域。ChatGPT本身需要依赖大量的训练对话数据和算法运行&#xff0c;其所依赖的对话数据&#xff0c;需要专业的数据采集标注处理流程才…