- 快召唤伙伴们来围观吧
- 微博 QQ QQ空间 贴吧
- 文档嵌入链接
- 复制
- 微信扫一扫分享
- 已成功复制到剪贴板
C++反射的应用于实践
展开查看详情
1 .C++反射的应用与实践 卜恪 PureCPP
2 . 什么是反射? 2018中国C++大会-purecpp.org 程序对自身程序结构认知的能力 • 能够使用数据结构来描述数据类型和其成员 • 能够主动地遍历这些成员
3 . 反射可以做什么? 2018中国C++大会-purecpp.org 序列化与反序列化 GUI库中对数据显示的自动化 对象关系映射(ORM) 与其他语言互操作 提供更强大的运行期特性
4 . C++反射现状 2018中国C++大会-purecpp.org 没有原生的语言反射基础设施 只有一个在TS状态的反射提案 还有cppers造轮子的血泪史 2018中国C++大会-purecpp.org
5 . Struggle On Reflection 2018中国C++大会-purecpp.org 静态反射 • 编译期反射 - 编译期的数据结构 • 离线期反射 - 代码生成 动态反射 - 运行期的数据结构 野路子 2018中国C++大会-purecpp.org
6 . 反射元信息 2018中国C++大会-purecpp.org 类型的元信息 • 成员字段的元信息 • 参数元信息 • 字段的参数元信息 • 参数名 • 成员方法的元信息 • 参数的类型元信息 • 方法名 • 构造函数的元信息 • 方法的形参参数元信息 • 形参参数元信息 • 方法返回参数的元信息 • More … • 基类的元信息
7 .项目中反射的应用 2018中国C++大会-purecpp.org C++ Core 引擎接口 GamePlay接口 引擎特性边界 业务边界 静态反射预处理 Runtime Bridge C++动态类型运行时 CLI运行时 Lua MemoryScope Virtual Machine Scheduler VM CORE Editor RunScope 策划边界 Execute Model Behavior Tree Node Graph State Machine Scripting 2018中国C++大会-purecpp.org
8 .1. 静态反射 a. 编译期与离线期的对比 b. 离线期的实践 目 录 2. 动态反射与动态类型运行时 3. 编译期反射 a. 现有设施下的实践 b. 未来的新标准 2018中国C++大会-purecpp.org
9 . 静态反射 - 编译期 2018中国C++大会-purecpp.org 标记方式 • 侵入式 • 能够处理私有成员 • 侵入导致对类型的修改 • 处于class-scope • 非侵入式 • 只能处理公有成员 • 无需修改需要标记的用户类型 • 处于namespace-scope
10 . 静态反射 - 编译期 2018中国C++大会-purecpp.org 数据访问 • 等价tuple • 类型 • 与反射类型大小及对其属性相同 • 指向成员的指针(pointer to member data)的列表 • 编译期常量 • 无需考虑大小及对其属性
11 . 编译期反射 - 遍历 2018中国C++大会-purecpp.org 显式地遍历访问 • static-for using std::index_sequence visitor模式 • 类似visitor访问boost.variant
12 . 静态反射 - 离线期 2018中国C++大会-purecpp.org 在编译前解析程序的AST • 通常仅解析接口头文件 遍历AST生成结构化数据 • AST的结构不利于数据的访问 • 提取类型和模板的引用关系 Code Generation
13 . 2018中国C++大会-purecpp.org 编译期反射 离线期反射 语法和语义都完整 许多语法和语义丢失 受限于C++编译器的特性 独立之外的预处理程序,能够实 需要实现额外的编译期代码的中间 现复杂的需求 层 需要生成额外的代码
14 . 静态反射 - 选型 2018中国C++大会-purecpp.org 静态反射承担引擎接口到业务逻辑层的导出工作 编译期反射由于语言设施还不够完善,有需求无法满足 编译期将引入大量的标记代码 编译期将引入大量而不可控的模板元代码 选择以离线期反射作为静态反射的方案
15 .项目的离线期工具clangen 2018中国C++大会-purecpp.org 代码生成 生成cli外观 提供给编辑器 libclang 生成JSON读写 序列化与反序列化 引擎接口 头文件 AST 结构化数据 生成Lua binding的代码 提供给Lua脚本 生成动态类型运行时 增强C++的动态特性
16 . 项目的离线期工具clangen 2018中国C++大会-purecpp.org Libclang解析接口头文件 • 将Libclang导入到C# • ClangSharp自更新 遍历Libclang AST生成结构化数据 模板引擎DotLiquid作代码生成
17 . Libclang的使用 2018中国C++大会-purecpp.org 设置系统头文件路径 妥善处理C++的类型 Libclang的一些使用限制
18 . 设置头文件路径 2018中国C++大会-purecpp.org 确定VCTool Chain的版本 • Microsoft.VisualStudio.Setup.Configuration寻找VisualStudio的安装目录和配置 • $(YourVisualStudioPath)/VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt 查询注册表确定Windows Kits的安装目录 确定libclang include命令行参数 • 计算$(VC_IncludePath)与$(WindowsSDK_IncludePath)绝对路径 • 绝对路径作为-I参数
19 . 处理C++的类型 2018中国C++大会-purecpp.org 内建类型和抽象数据类型(ADT) 类型修饰符带来的衍生类型 • const和volatile修饰符 • 指针类型 • 左值与右值引用 • 数组,尤其是大小未明确的数组类型(int a[]) • 指向成员的函数及指向成员的数据类型 Type define & type alias • namespace-scope & class-scope • 从基类继承而来的 • 依赖模板参数的类型
20 . 使用限制 2018中国C++大会-purecpp.org Libclang可以且仅能看到源码的AST • 合成的函数和操作符对AST不可见 • 类模板实例化后的实体类型的结构对AST不可见 模板的类型参数坍塌 • typedef和type alias会丢失 • std::string到basic_string<char, char_traits<char>, allocator<char>> 无法准确地索引到实例化类型的模板特化 • 全特化是普通类,可以正确处理 • 偏特化只能索引到主模板
21 .使用限制 2018中国C++大会-purecpp.org
22 . 项目的离线期工具clangen 2018中国C++大会-purecpp.org 对模板的支持 • <type_traits> on Clang AST • 处理的是实例化的类型,而不是处理模板 • 处理了标准库的容器及迭代器 • 统一处理字符串
23 . 一点小建议 2018中国C++大会-purecpp.org 原则上避免在模块级别的接口中使用模板 • 为libclang的使用招致诸多麻烦 • ABI问题和ODR问题 可以避免接口头文件包含系统头文件
24 .编译期的C++ 2018中国C++大会-purecpp.org
25 .运行期的C++ 2018中国C++大会-purecpp.org 爱裸奔 类型擦除
26 . 运行期设施简陋 2018中国C++大会-purecpp.org typeof operator 和 std::type_info virtual table: 动态分派 dynamic_cast: 动态类型转换
27 . 动态反射 - 需要完善的设施 2018中国C++大会-purecpp.org 运行时获取类型的元信息 通过类型的元信息操作实体对象 • 成员变量的访问和设置 • 成员函数的调用 • 运行期的类型检查与类型转换 与静态代码解耦,消除 • 显式的表达式 • 显式的字面量 • 显式的函数调用 SCRIPTING! C++动态类型运行时
28 .动态反射 - PONDER 2018中国C++大会-purecpp.org
29 . 动态反射 - PONDER 2018中国C++大会-purecpp.org 注册类型的元信息到runtime type system中 通过元信息创建默认实例 对字段的Get和Set 通过成员方法的元信息调用方法