最近在思考如何在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++中实现反射的初步想法的更多相关文章

  1. .Net 中的反射(序章) - Part.1

    引言 反射是.Net提供给我们的一件强力武器,尽管大多数情况下我们不常用到反射,尽管我们可能也不需要精通它,但对反射的使用作以初步了解在日后的开发中或许会有所帮助. 反射是一个庞大的话题,牵扯到的知识 ...

  2. 详解C#中的反射

    反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的生理情况.这是如何做到的呢?B超是B ...

  3. python中的反射

    在绝大多数语言中,都有反射机制的存在.从作用上来讲,反射是为了增加程序的动态描述能力.通俗一些,就是可以让用户参与代码执行的决定权.在程序编写的时候,我们会写很多类,类中又有自己的函数,对象等等.这些 ...

  4. .net中的反射(转载)

    原文地址:http://www.cnblogs.com/Stephenchao/p/4481995.html 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的 ...

  5. [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦

    [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...

  6. Java中的反射和注解

    前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...

  7. java中的反射机制在Android开发中的用处

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...

  8. Go 中的反射要点

    简介 反射是元数据编程的一种形式,指的是程序获得本身结构的一种能力.不同语言的反射模型实现不一样,本文中的反射,仅仅指的是Go语言中的反射模型. 类型以及接口 这个基本概念需要清晰,这里不详细展开. ...

  9. 【转】详解C#中的反射

    原帖链接点这里:详解C#中的反射   反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子: 1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内 ...

随机推荐

  1. python的==和is区别

    Python中: is判断两个标识符是否引自同一个对象 ==判断两个标识符的值是否相等 区别于java: ==判断两个标识符是否引自同一个对象 .equals()判断是否相等   #如果是String ...

  2. kafka问题集(二):__consumer_offsets topic的分区中有一个分区数据很多,多达1T

    仅个人实践中所遇到的问题,若有不对的,欢迎交流! 一.场景描述 kafka集群中有几台突然挂了,后台日志显示设备空间满了,消息无法写入__consumer_offsets topic的分区中了.查看k ...

  3. 【bzoj4031】[HEOI2015]小Z的房间 解题报告

    [bzoj4031][HEOI2015]小Z的房间 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含\(n*m\)个格子的格状矩形,每个格子是一个房 ...

  4. IO编程(2)-操作文件和目录

    操作文件和目录 如果我们要操作文件.目录,可以在命令行下面输入操作系统提供的各种命令来完成.比如dir.cp等命令. 如果要在Python程序中执行这些目录和文件的操作怎么办?其实操作系统提供的命令只 ...

  5. CAS使用心得

    1.理解CAS实现SSO需要哪些组成部分 2.理解CAS实现SSO流程,包括登陆.注销.二次登陆.其他应用登陆 3.CAS部署需要SSL支持,理解容器如何开启SSL.服务端证书.jre证书信任.创建以 ...

  6. hdu 6311 欧拉回路

    题意:求一个图(不一定联通)最小额外连接几条边,使得可以一笔画出来 大致做法 1.找出联通块 2.统计每一个连通块里面度数为奇数的点的个数, 有一个性质 一个图能够用一笔画出来,奇数点的个数不超过2个 ...

  7. bzoj 4332 FFT型的快速幂(需要强有力的推导公式能力)

     有n个小朋友,m颗糖,你要把所有糖果分给这些小朋友. 规则第 i 个小朋友没有糖果,那么他之后的小朋友都没有糖果..如果一个小朋友分到了 xx 个糖果,那么的他的权值是 f(x) = ox^2 +  ...

  8. vi的一些使用技巧

    1.vi 编辑器中跳到文件的第一行:键盘按下 小写 gg   vi 编辑器跳到文件最后一行:键盘按 shift + g (等于G) 跳转到当前行的第一个字符按0,跳转到当前行的最后一个字符按shift ...

  9. 在Kubernetes集群里安装微服务DevOps平台fabric8

    转载于https://blog.csdn.net/wzp1986/article/details/72128063?utm_source=itdadao&utm_medium=referral ...

  10. 彻底搞懂 SQLAlchemy中的 backref

    教程源码截取: class User(Base): __tablename__ = 'user' id = Column(Integer, primary_key=True) name = Colum ...