- 主题:如何写一个函数能够序列化任意结构
【 在 ylh0315 的大作中提到: 】
: 我这个没有预编译。
: 先看一个结构:
:
: ...................
现在给它配模板:
T_PkgType st_tpl[]={
{CH_TINY,1,"c",0,-1},
{CH_INT64,sizeof(INT64),"bi"},
{-1,0,0,0}
};
T_PkgType ss_tpl[]={
{CH_TINY,1,"c",0,-1},
{CH_STRUCT,0,"s",(const char *)st_tpl},
{CH_INT,sizeof(int),"i"},
{-1,0,0,0}
};
这是一个.c,include到任何一个.c或.cpp里即可。
--
FROM 221.221.50.*
//这个就是所谓的“模板”了,它使我们能够"看"到未知结构的内容。
typedef struct {
INT4 type;
INT4 len; // in byte
const char *name;
const char *format;
INT4 offset;
int bindtype; //default=0
} T_PkgType;
模板结构定义,每个成员一套,多个成员按次序组成数组。所有成员最后加一个尾标,type=-1;相当于尾零。
看楼上都有这么一行: {-1,0,0,0}
注意那个offset,就是成员相对于结构头的偏移量。写模板时不需要写。
第一个成员的offset写-1,这个是必须的。
第一次被使用时,程序发现这个是-1,就自动计算每个成员的offset,这一步就是倒推结构布局。计算结果,第一个成员的offset必定是0;这个就保证了计算只发生一次,这个系统的运行效率是非常高的。
【 在 ylh0315 的大作中提到: 】
: 现在给它配模板:
: T_PkgType st_tpl[]={
: {CH_TINY,1,"c",0,-1},
: ...................
--
修改:ylh0315 FROM 221.221.50.*
FROM 221.221.50.*
【 在 ylh0315 的大作中提到: 】
: //这个就是所谓的“模板”了,它使我们能够"看"到未知结构的内容。
: typedef struct {
: INT4 type;
: ...................
看看程序是怎样的:
JSON_OBJECT stu_to_json(JSON_OBJECT json,void *data,T_PkgType * typ,const char *choose,char *colidx)
{
int i,colnum,n;
T_PkgType *tp;
char buf[100];
const char *cp;
if(!json) return json;
colnum=set_offset(typ);//第一个offset是-1,就计算,否则直接返回。
tp=typ;
if(!choose||!*choose) { // 没有选择,全部加入
for(i=0;tp->type>=0;i++,tp++) {
if(tp->bindtype & NOSELECT) continue;//如果select不要这个,序列化也不要。
if(choose&&isnull((char *)data+tp->offset,tp->type)) continue;
if(tp->type==CH_STRUCT) {
JSON_OBJECT sub=json_object_new_object();
stu_to_json(sub,(char *)data+tp->offset,
(T_PkgType *)tp->format,0,0);
json_object_object_add(json,plain_name(tp->name),sub);
continue;
}
add_field_to_object(json,data,tp);
}
return json;
}
这个函数比我前边给的多了几个参数,不要紧,前三个一样,后边写0即可。
--
修改:ylh0315 FROM 221.221.50.*
FROM 221.221.50.*
应用场景:
从数据库得到一些“行”,或者叫做“rows”。放到结构里。然后序列化,返回到前端。
前端提出需要取数的表名和检索条件,先用模板生成SQL语句,经过数据库操作,把结果集反序列化到结构。
【 在 ylh0315 的大作中提到: 】
: 看看程序是怎样的:
: JSON_OBJECT stu_to_json(JSON_OBJECT json,void *data,T_PkgType * typ,const char *choose,char *colidx)
: {
: ...................
--
修改:ylh0315 FROM 221.221.50.*
FROM 221.221.50.*
算不算,反正解决问题。
做了一套SRM系统,可以高效率的访问数据库。
实现柔性编程,一个功能模块,可以处理好几个表。
【 在 littleSram 的大作中提到: 】
: 你这不算啊
--
FROM 221.221.50.*
23楼的程序,就是可以处理任意结构呀。
【 在 littleSram 的大作中提到: 】
: 你这不算啊
--
FROM 221.221.50.*
我们都是这样的呀!
都得分段。
读数据库时,就是一个row一个结构,一个结构一个json,你想进行二进制表达也行,有个XDR工具。
循环读出所有的内容。必要时分包。这都是你的事。
【 在 allegro 的大作中提到: 】
: 序列化,反序列化有没有人实现过这这个功能:
: 对于struct A,序列化后会生成一个极其长的byte stream,比如1TBytes大小。
: 然后把这个1T写入存储。
: ...................
--
修改:ylh0315 FROM 221.221.50.*
FROM 221.221.50.*
23楼的函数,循环使用,想怎么分包就怎么分包。
【 在 allegro 的大作中提到: 】
: 序列化,反序列化有没有人实现过这这个功能:
: 对于struct A,序列化后会生成一个极其长的byte stream,比如1TBytes大小。
: 然后把这个1T写入存储。
: ...................
--
FROM 221.221.50.*
20楼有例子,你看是不是。
不是说第三方软件里的结构指的啥?
【 在 ylh0315 的大作中提到: 】
: 23楼的函数,循环使用,想怎么分包就怎么分包。
--
FROM 221.221.50.*
是。但是C语言没有反射功能。即编译后没有保留结构的信息。(确切说,运行时是没有结构这个概念的,其实只是变址访问内存而已)
所以需要补充meta信息。模板就是补全这个信息。
技术要点是offset的计算,攻克这点,其他没难度。模仿编译器的各种类型的对齐规则。
其中一部分内容就是逼迫编译器,交出他的对齐规则。
【 在 rexxie 的大作中提到: 】
: 这不就是meta data么?不还是反射那一套么?
:
--
修改:ylh0315 FROM 221.221.50.*
FROM 221.221.50.*