您的位置:首页 > 其它

c 结构体反射机制实现

2013-11-23 15:49 381 查看
需要为一个结构体Struct  RequestParam 中的成员变量赋值。

定义一个新的结构体

struct RequestSetter{
size_t offset;   //成员变量的 offset
RequestFieldType type;   //成员变量的类型
RequestSetter(){
}
RequestSetter(size_t field_offset, RequestFieldType field_type):
offset(field_offset), type(field_type) {
}
};

需要提前注册 Request 中成员变量的 赋值信息,例如:下面的代码 FD_INT表示成员变量的类型
param_map_[ "group" ] = RequestSetter(
myoffsetof(RequestParam,_M_group), FD_TXT);
param_map_[ "kw" ] = RequestSetter(
myoffsetof(RequestParam, _M_word), FD_TXT);
param_map_[ "orig" ] = RequestSetter(
myoffsetof(RequestParam, _M_orig), FD_TXT);
param_map_[ "filter" ] = RequestSetter(
myoffsetof(RequestParam, _M_cond), FD_TXT);

然后对Request的成员变量赋值时仅需要保证根据其注册信息就可方便的实现:  例如

void SetRequestField(
RequestSetter* setter, RequestParam* request, char* value) {
char * base = (char*) request;
switch(setter->type){
case FD_TXT:
DecodeParameter(value);
*((std::string*)(base+setter->offset)) = std::string(value);
break;
case FD_INT:
*(int*)(base+setter->offset) = strtol(value, NULL, 10);
break;
case FD_INT_TRANSFER:
*((int*)(base+setter->offset)) = strtol(value, NULL, 0);
break;


其中最重要的一点是计算每个成员变量的offset 

#define myoffsetof(st, m) ((size_t)(&((st *)1)->m)-1)


这个宏的含义在于将地址空间为1的内存强转为需要赋值的类型(st),即(RequestParam), 然后取某个成员变量(m)的地址 -1以后即为偏移量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: