资讯动态

archimedes反射运行时详解:reflect<T>()一行代码反射任意C++类型

发布时间:2026/8/23 13:03:42 来源:尧图企业网站定制
archimedes反射运行时详解reflect ()一行代码反射任意C类型【免费下载链接】archimedesC20 reflection via code generation项目地址: https://gitcode.com/gh_mirrors/ar/archimedesarchimedes是一个 C20 反射库通过 clang 插件在编译期采集类型信息让reflectT()一行代码就能在运行时反射任意 class、struct、enum 或函数——读取字段、调用方法、枚举值与字符串互转全部开箱即用。什么是 archimedes不用宏也能拥有 C 反射C 标准库迟迟没有真正的反射很多项目靠Q_OBJECT这类宏或手写样板代码解决。archimedes 的思路完全不同它不修改你的类型定义。编译器正常编译你的代码archimedes 的clang 插件在已实例化的 AST 上遍历、采集类型信息序列化后额外生成一个*.types.o目标文件和正常产物一起链接。程序启动时调用一次archimedes::load()加载元数据之后reflectT()随用随取。这意味着✅ 你的现有 C 代码零侵入一个宏都不用加✅ 模板类天然支持只要被程序真正实例化✅ 元数据以字节数组内嵌进程序运行期反序列化编译时间几乎不受影响reflect () 一行代码能做什么调用示例完整演示见 test/example.test.cpp#include archimedes.hpp int main() { archimedes::load(); // 启动时加载一次 auto t archimedes::reflectFoo(); // 反射任意类型 }reflectT()会根据 T 的种类自动返回不同的反射对象见 include/archimedes.hpp 中的一组requires约束重载类型种类返回对象典型能力class / struct / unionreflected_record_type字段读写、基类、内存布局、方法调用enumreflected_enum_type值 ↔ 字符串互转、底层类型函数reflected_function_type列出参数名称、类型、限定符并 invoke数组 / 成员指针等对应反射类型继续向下追溯对一个被反射的类你可以拿到模板参数的名称、类型、取值字段包括private成员及在活对象上 get/set 值基类链虚拟基类、vtable 指针、对象内存布局⚡函数与静态函数可直接对活对象调用️构造/析构函数在裸内存上初始化或销毁对象类型特征is_abstract/is_polymorphic/is_pod等静态字段及其值constexpr 字段还能取常量值typedef / using别名与类型大小、对齐信息此外还支持按名字反射archimedes::reflect(Foo)、按注释annotations查找reflect_by_annotations()以及reflect_children()直接列出某个基类的全部子类——写序列化器、调试器、场景编辑器时非常顺手。如何编译安装clang 插件 三步走构建需要 LLVM/clang 开发环境项目自带 Makefile 一键构建插件与库$ make plugin static shared编译你自己的代码时给 clang 挂上插件参数即可$ clang -o main.o -c main.cpp \ -fpluginpath_to_archimedes \ -fplugin-arg-archimedes-header-include/archimedes.hpp \ -fplugin-arg-archimedes-exclude-ns-std \ -fplugin-arg-archimedes-file-main.cpp \ -fplugin-arg-archimedes-out-main.types.o $ clang -o main main.o main.types.o要点解析-fplugin-arg-archimedes-header-...指向 archimedes 头文件-fplugin-arg-archimedes-file-...声明哪些文件中的类型需要被反射-fplugin-arg-archimedes-exclude-ns-std排除std等命名空间避免元数据爆炸-fplugin-arg-archimedes-out-...反射元数据输出为main.types.o最后与正常目标文件一起链接代码中还提供了ARCHIMEDES_ENABLE()/ARCHIMEDES_DISABLE()宏可按编译单元精细开关。源码导读从插件到运行时的关键文件想深入理解实现建议按数据流顺序阅读以下文件阶段文件职责编译期plugin/plugin.cppclang 插件入口遍历 AST编译期plugin/emit.cpp序列化类型信息并生成.types.o编译期plugin/invoker.cpp生成函数调用/构造的 invoke 逻辑运行期runtime/archimedes.cpp加载、反序列化元数据运行期common/registry.cpp类型注册表按 id / 名字查找APIinclude/archimedes/type_id.hpptype_id类型名的 FNV1a 编译期哈希APIinclude/archimedes/types.hppreflected_record_type等公开反射类型其中type_id的设计值得品味它利用__PRETTY_FUNCTION__在编译期拿到非修饰的类型名再用 constexpr FNV1a 哈希成 64 位整数从而让reflectT()无需任何字符串操作即可在运行期 O(1) 命中注册表。总结把类型信息变成运行时的数据archimedes 用代码生成换来了真正的 C 反射编译期做重活AST 遍历 序列化运行期只做一次轻量加载之后reflectT()一行代码即可枚举字段、调用方法、转换枚举。目前项目仍标记为 ALPHA接口可能变动但作为理解C 反射可以如何落地的样本它的 clang 插件 字节序列化方案值得收藏研究。【免费下载链接】archimedesC20 reflection via code generation项目地址: https://gitcode.com/gh_mirrors/ar/archimedes创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价