zoukankan      html  css  js  c++  java
  • 在c++中实现反射的初步想法

    最近在思考如何在c++中实现反射。事情的起因是这样的:我们服务器是用c++开发的,如果需要写一些测试用的GM指令的话,需要编写完GM代码后重新编译并且重启进程,工序繁琐且比较耗时。因此就有了想用脚本(lua或py)来写GM的想法。用脚本来做这事我觉得还挺适合的。首先可以免去编译、重启(通过脚本的reload)的过程。其次测试用的GM没有高性能的需求,并且一般在进行自测的阶段时,代码往往是频繁改动的,刚好适合用灵活的脚本:P

    接下来的问题就是,要如何在项目中引入脚本。考虑到使用场景,我觉得这个脚本机制最核心的一点就是:不需要显示的定义出c++暴露给脚本的接口。因为这块主要是在测试环境下工作,因此主要关注的是使用更便捷。如果每一个c++模块都需要再手动写一个wrapper类才能用脚本调用它,这样就太繁琐了,完全背离了减负的初衷。

    首先我想到的是自动生成wrapper类的代码,比如说使用SWIG。方法可以是把需要生成wrapper的模块(实际上c++没有模块,只有编译单元)的文件名集中写在一个文件,在编译构建时扫描文件中记录的模块,统一生成wrapper类。但这样其实并没有做到业务代码完全无感知,只是把写wrapper类的工作优化成写模块名:-(

    那么扫描项目中的所有模块呢?不管是否需要,统统都生成一份wrapper。这似乎可行。不过我先不考虑它,因为我心里还有另外一个方法。 

    在前一个项目中,我了解到了一种通过反射来在c#中嵌入cpython虚拟机的方法。因此我在想,如果能在c++中实现一个反射,那不就可以做到用脚本调用c++代码了吗。

    要在c++实现反射,不可避免的是要把一个模块(编译单元)的入口记录下来。其中入口包括了函数、全局变量、类的类型信息等等。一般的做法可能是显示的定义出一个模块的入口。优雅一点的可能是在.h文件里稍动手脚,悄悄的把入口信息记录下来。

    但是我更希望是,在实现反射时能对原有代码做尽可能少的改动。并且最好可以和业务代码完全的分离。在线上环境下,能够不产生任何性能开销。因此,我想到了是另外一种方法。

    实际上在编译的过程中,是有模块的入口信息的(比如说符号表)。但是在编译完之后,这些信息就被丢掉了。如果把这些编译的中间信息存下来,存成一个单独的文件,那么在运行时就可以在通过在文件中查找对应的信息,来实现反射了。类似于在调试时通过载入可执行文件对应的pdb,来获取调试信息一样。

  • 相关阅读:
    C# 不用添加WebService引用,调用WebService方法
    贪心 & 动态规划
    trie树 讲解 (转载)
    poj 2151 Check the difficulty of problems (检查问题的难度)
    poj 2513 Colored Sticks 彩色棒
    poj1442 Black Box 栈和优先队列
    啦啦啦
    poj 1265 Area(pick定理)
    poj 2418 Hardwood Species (trie树)
    poj 1836 Alignment 排队
  • 原文地址:https://www.cnblogs.com/adinosaur/p/9693930.html
Copyright © 2011-2022 走看看