用C实现反射机制
所需工具:g编译器
前言:
本文主要探讨并实现了如何用C实现类似于。NETJAVA的反射机制。
探讨:
近由于项目需求,我们需要用C编写一个脚本执行程序(简而言之,是编写一个脚本执行框架)。但是很不幸的是,C中并没有一种想相关的机制来仅仅通过一串函数名的字符串来对应执行函数(反射机制)。
举个实际的例子吧:
我现在有这么一个类:
TestClassA{
Voidfunc0();
Voidfunc1();
};
那么我希望在我的mian函数中如果出现TestClassA::func0这样的字样的话,我能够通过某种方法真的执行这个函数(注意:不能再编写代码时写死哦)
其实,C中也不是真的不支持反射,比如C11的RTTI中的typeid就有那么一点点萌芽,但是很可以的是,RTTI的重点在于类型检查,而不是执行具体方法。
废话不多说了,开始正式思路探讨吧。
思路:
我研究了一下JAVA的反射,他们是这样用的
FoofoonewFoo(这个一个Foo对象!);
Classclazzfoo。getClass();
Methodm1clazz。getDeclaredMethod(outInfo);
Methodm2clazz。getDeclaredMethod(setMsg,String。class);
Methodm3clazz。getDeclaredMethod(getMsg);
m1。invoke(foo);
m2。invoke(foo,重新设置msg信息!);
Stringmsg(String)m3。invoke(foo);
System。out。println(msg);
(引用地址:http:lavasoft。blog。51cto。com6257561002)
那么我觉得JAVA编译器在编译过程中肯定是对Foo类中的各种成员函数进行了序列化,并把它放到了一个容器中。当我们要反射时,便会从这个容器中去除对应函数的函数指针然后通过回调函数执行。
那么我们的思路应该是:
0定义一个函数指针,该函数指针应该与我们要反射的函数同类型。
1创建以一个反射类,该类负责序列化自写类中的方法,并将其放入一个map容器中
2在main函数运行前,将我们可能被反射的函数进行注册
代码:
0定义函数指针(当然我们的函数也要写成这样子的)
typedefvoid(TestClassA::PTRDeclareFunc)(int,int);
1定义反射类
注意:反射类应该是单例模式;应该有一个静态方法来反射;应该有一个方法来注册;
classReflectAction{
private:
mapstring,PTRDeclareFuncmclassFuncMap;
ReflectAction(){}
public:
staticReflectActiongetFuncInstance();
voidgetClassFuncByName(stringclassName,inta,intb)
{
mapstring,PTRDeclareFunc::constiteratoriter;
itermclassFuncMap。find(className);
if(itermclassFuncMap。end())
return;
else
{
TestClassAqnewTestClassA;
PTRDeclareFuncpitersecond;
(qp)(a,b);
}
return;
}
voidregistClassFunc(stringname,PTRDeclareFuncmethod)
{
mclassFuncMap。insert(pairstring,PTRDeclareFunc(name,method));
}
};
ReflectActionReflectAction::getFuncInstance(){staticReflectActionsigleClass;returnsigleClass;}
2为我们书写的类进行注册
(我们用宏的方式来代替手动书写,这样比较节省书写时间)
注意:attribute((constructor))该关键字指该函数在main函数执行前运行
defineREGISTER(className,funcName)
attribute((constructor))voidbeforemainclassNamefuncName()
{
ReflectAction::getFuncInstance()。registClassFunc(classNamefuncName,className::funcName);
}
使用方法是:
REGISTER(TestClassA,mfunc);
3我们自己的类是:
classTestClassA{
public:
voidmfunc(inta,intb);
};
voidTestClassA::mfunc(inta,intb){
couthelloTestClassAabendl;
};
4main函数是:
intmain(intargc,charargv〔〕){
ReflectAction::getFuncInstance()。getClassFuncByName(TestClassAmfunc,1,1);
}
好的,代码难度不大,以上代码只是关键代码。大家可以下载出源码自行实验:
https:github。comBasicLinuxFunnyZone里面有一个文件叫CPPReflect。cpp的文件。
执行效果:
嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!
分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!加微信领取资料
兜底失败!中顺洁柔跌去280亿,老板补偿2500万,股民怎么办?文张佳儒历时一年,中顺洁柔兜底迎来大败局。6月2日盘后,中顺洁柔发布公告,实际控制人邓颖忠倡议员工增持公司股票承诺事项履行完毕,截至5月30日,符合补偿条件的员工共264名,符合补
退休之后,还要去打工的人,多半是以下几种人很多人退休了过后依然选择继续上班,有时候他根本就不缺钱可是他为什么还要继续上班呢?其实很多人退休过后他是不愿意去上班的,可是因为生活上的拮据被逼无奈最终他只能奔赴一线,那到底是什么
把大国粮仓的根基夯得更实坚持分级分区分类差异化疫情防控,只要条件允许方法得当,就要确保农民能下田农资能下摆农机能上路外出农民能返乡务农端午时节,广袤田野里,农机纵横驰骋,农民辛勤耕耘,田间地头一派大忙景象
俄罗斯为什么会允许修建中吉乌铁路?被俄罗斯阻挡了20年的中吉乌铁路,在三国的不懈努力下,终于能够修建了。不出意外,只需要2年,在项目合同交付日期前,中国就能够修建完工。这条铁路将采用与中国相同的标准轨距,而不是俄式
2022高考倒计时5天!遇见中国医大,触摸成长无限可能!高考的倒计时,已经悄然来到第5天,现在的你可能仍对未知的前途和无法预测的人生走向一边担忧,一边期待着。但是请别着急,背单词时,阿拉斯加的鳕鱼正跃出水面算数学时,太平洋彼岸的海鸥振翅
结构性牛市开启本文章都是唯一的,文章观点只代表个人对大盘的看法,任何人的操作必须按自己思路来进行,本号文章只是给你一个参考,你的盈亏由你自己负责,与本号文章无关,个人有个看法股市大多数人不适合投
美媒003航母是中国有史以来最大的航空母舰,或被命名为江苏舰在2022年4月23日中国海军节前一天,中国海军发布航母主题宣传片深蓝!深蓝!,结尾暗示第三艘国产航母即将下水(即第三胎航母),这也是官方机构官宣万众期待的中国新型航母距离正式公布
2022本报告研究十三五期间全球及中国市场隔膜墙设备的供给和需求情况,以及十四五期间行业发展预测。重点分析全球主要地区隔膜墙设备的产能销量收入和增长潜力,历史数据20172021年,预测数
刘亦菲在剧组伙食太好?新照穿印花裙勒出双层游泳圈,太接地气了刘亦菲在大众的印象里一直都是高颜值代言人,因此还被粉丝赞誉为神仙姐姐,不过最近这几年,刘亦菲的身材一直不是特别稳定,忽胖忽瘦,在刚曝光的新剧片花中她的古装造型就仙气飘飘,而最新的拍
把大国粮仓的根基夯得更实坚持分级分区分类差异化疫情防控,只要条件允许方法得当,就要确保农民能下田农资能下摆农机能上路外出农民能返乡务农端午时节,广袤田野里,农机纵横驰骋,农民辛勤耕耘,田间地头一派大忙景象
当遇到爱情时,不要逃避,也不是没有勇气去面对它,但已经爱上唐如意娘武则天看朱成碧思纷纷,憔悴支离为忆君不信比来长下泪,开箱验取石榴裙。武则天的故事大家应该都是在电视上了解得比较多的吧!影视剧上描写的各种各样的都有,其实武则天她是一个很有才