C反射反射信息的自动生成

导语

本文将结合笔者的项目经验,介绍如何在C#中用一种逐层处理的方式完成前文中提到的反射注册信息的自动生成的,希望为更多感兴趣的开发者提供一点经验和帮助。

在前一篇中:《C++反射:全方位解读Lura库的前世今生!》我们介绍了如何利用c++反射的基础设施来实现一个lua中间层。其中也有一些注册代码的示例。

当项目比较简单的时候,手动编写相关的反射注册代码不会占用太多的时间。但当项目达到一定规模,手动编写并维护这些注册代码费时费力,相关接口改个名可能会涉及到多处关联注册代码的修改,这肯定是我们所不能接受的。

所以大部分项目在使用反射,或者类反射的脚本中间层生成的过程中,都会开发一些自动生成工具来减少重复性的工作,笔者所经历的项目也是如此。

得益于llvm的流行,我们大部分相关工具都是以libclang解析源代码头文件生成AST作为基础的。

本文将结合笔者的项目经验,介绍如何在C#中用一种逐层处理的方式完成前文中提到的反射注册信息的自动生成的。

一、示例代码

前文中也提到过,对于一个c++中的Vector3的定义:

//-------------------------------------//declaration//-------------------------------------classVector3{public:doublex;doubley;doublez;public:Vector3():x(0.0),y(0.0),z(0.0){}Vector3(double_x,double_y,double_z):x(_x),y(_y),z(_z){}doubleDotProduct(constVector3vec)const;};

我们通过反射注册代码:

//-------------------------------------//registercode//-------------------------------------__register_typeVector3("Vector3").constructor().constructordouble,double,double().property("x",Vector3::x).property("y",Vector3::y).property("z",Vector3::z).function("DotProduct",Vector3::DotProduct););即可以完成对它的构造函数以及几个属性的反射注册,然后我们就可以通过反射库来使用它了。

代码自动生成的目的比较简单,对于上面的代码来说,我们通过定义部分代码信息的读取,能够完成对应的注册代码的自动生成,整个任务就算是完成了。

早期没有llvm库的时候,我们只能通过正则匹配等字符串模式匹配的方式来完成相关工作,这种方式比较大的弊端一方面是效率,另外一方面是业务程序对代码的组织方式可能破坏自动工具的工作,排查和定位相关问题又不是那么直接。在llvm库流程后,越来越多的人开始尝试在AST这一层对源代码信息进行提取,这样相关的问题就回归到了c++本身来解决了,这肯定比前面说的基于字符串的机制要稳定可控非常多,相关的问题也更容易定位排查。要使用这种方式,我们先来简单的了解一下libclang。

二、libclang和它带来的改变

libclang是llvm工具链中的一部分,整个llvm的工作过程简单来说可以看成下图所示:

而libclang主要用于处理c++源码-AST这部分的工作。

在llvm出现前,c++的


转载请注明:http://www.aierlanlan.com/cyrz/705.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了