- 主题:[求助]大型struct填充
那也得一个一个字段的赋值
【 在 z16166 的大作中提到: 】
: 数据预处理成json/xml之类的格式化数据,然后用json/xml的反序列化库自动填充struct就行了
--
FROM 221.221.52.*
没看明白,怎么把值赋到结构成员里的。
j.temlate是个待解的迷。
【 在 z16166 的大作中提到: 】
: 反序列化不需要挨个字段赋值,比如
: nlohmann::json j = nlohmann::json::parse(jsonString);
: auto order = j.template get<xstruct>();
: ...................
--
FROM 221.221.52.*
你在本版搜一下作者 ylh0315,结果里有一个 如何写一个函数能够序列化任意结构。打开看看。
https://www.newsmth.net/nForum/#!article/CPlusPlus/423333
重点看20~23楼,例子是序列化,反序列化(对结构赋值)的道理是一样的。
由于C不提供结构体的反射功能,所以需要一个结构说明书,就是模板。
这个模板的产生,有三个方法:
1,手写,结构体的每个成员描述出来。只要列举一次,就可以解决序列化反序列化,数据库操作:生成SQL语句,绑定变量,取值赋值等等所有问题。
2,利用数据库的表字典自动生成模板。这可以用于动态数据库访问。
3,写元数据文件,通过工具生成成对的结构体和模板。这算是半自动吧。
利用反射提取参数是有些开销的,在JAVA里。但是利用模板就比较直接,速度是更快的。
如果感兴趣,可以加入QQ群:SDBC技术群,到群空间下载文档和源码,在linux环境下使用。有问题可以在群里讨论。
【 在 dajun 的大作中提到: 】
: 真正上古代码,一群真正智障在改.
: 比如:
: [code=c]
: ...................
--
修改:ylh0315 FROM 221.221.52.*
FROM 221.221.52.*
【 在 z16166 的大作中提到: 】
: 反序列化不需要挨个字段赋值,比如
: nlohmann::json j = nlohmann::json::parse(jsonString);
: auto order = j.template get<xstruct>();
: ...................
这个是反序列化程序,符合楼主要求。我只得老老实实写个程序。
int json_to_struct(void *data,JSON_OBJECT json,T_PkgType *typ) //typ就是模板,template
{
T_PkgType *tp; //模板指针,指向一个成员的描述。
int i,num;
JSON_OBJECT val;
char *cp;
num=0;
if(!json) return 0;
if(typ->offset<0) set_offset(typ);
tp=typ;
for(i=0;tp->type>=0;i++,tp++) { //遍历模板,对于每个成员名,从JSON中寻找内容
if(tp->type == CH_STRUCT) { //结构套结构,递归
val=json_object_object_get(json,plain_name(tp->name));
if(!val) continue;
json_to_struct((char *)data+tp->offset,val,(T_PkgType *)tp->format);
continue;
}
if((val=json_object_object_get(json,plain_name(tp->name)))!=NULL) {
cp=(char *)json_object_get_string(val);
put_str_one(data,cp,tp,0); //这条是关键,把数据放到一个成员里。
num++;
}
}
return num;
}
--
修改:ylh0315 FROM 221.221.52.*
FROM 221.221.52.*
【 在 ylh0315 的大作中提到: 】
:
: 这个是反序列化程序,符合楼主要求。我只得老老实实写个程序。
: int json_to_struct(void *data,JSON_OBJECT json,T_PkgType *typ) //typ就是模板,template
: ...................
看看它干了啥:
int put_str_one(void *buf,char *cp,T_PkgType *typ,char CURDLM)
{
int ret;
register char *cp1;
cp1=typ->offset+(char *)buf; //找到成员的位置
ret=0;
switch(typ->type) { //判断类型
case CH_CLOB:
*(char **)cp1=cp;
if(CURDLM) strcpy_esc(cp,cp,-1,CURDLM); //有问题
typ->len=strlen(cp);
ret=1;
break;
case CH_BYTE:
byte_cpy(cp1,cp,typ->len);
ret=1;
break;
case CH_DATE:
case CH_CNUM:
case CH_CHAR:
*cp1=0;
strcpy_esc(cp1,cp,typ->len,CURDLM);
ret=1;
break;
case CH_FLOAT:
*(float *)cp1=strtof(cp,&cp);;
ret=1;
break;
case CH_DOUBLE:
*(double *)cp1=strtod(cp,&cp);;
ret=1;
break;
case CH_LDOUBLE:
*(long double *)cp1=strtold(cp,&cp);
break;
case CH_JUL:
case CH_CJUL:
if(!*cp) *(INT4 *)cp1=INTNULL;
else if(typ->format){
*(int *)cp1=rstrfmttojul(cp,
typ->format);
} else {
*(int *)cp1= rstrjul(cp);
}
ret=1;
break;
case CH_MINUTS:
case CH_CMINUTS:
if(!*cp) *(INT4 *)cp1=INTNULL;
else if(typ->format){
*(INT4 *)cp1=rstrminfmt(cp,typ->format);
} else *(INT4 *)cp1=rstrmin(cp);
ret=1;
break;
case CH_TIME:
case CH_CTIME:
if(!*cp) *(INT64 *)cp1=INT64NULL;
else if(typ->format){
*(INT64 *)cp1=rstrsecfmt(cp,typ->format);
} else *(INT64 *)cp1=rstrsecfmt(cp,"YYYYMMDDHH24MISS"); //ORACLE的,其他数据库可能需要改变。
ret=1;
break;
case CH_USEC:
if(!*cp) *(INT64 *)cp1=INT64NULL;
else if(typ->format){
*(INT64 *)cp1=rstrusecfmt(cp,typ->format);
} else *(INT64 *)cp1=rstrusecfmt(cp,"YYYYMMDDHH24MISS.FF6");
ret=1;
break;
case CH_TINY:
{
int tmp;
if(!*cp) {
*cp1=TINYNULL;
break;
}
tmp=atoi(cp);
*cp1=(char)tmp;
break;
}
case CH_SHORT:
*(short *)cp1=SHORTNULL;
ret=sscanf(cp,"%hd",(short *)cp1);
ret=1;
break;
case CH_INT:
if(!*cp) {
*(int *)cp1=INTNULL;
break;
}
*(int *)cp1=atoi(cp);
break;
case CH_LONG:
if(!*cp) {
*(long *)cp1=LONGNULL;
break;
}
*(long *)cp1=strtol(cp,&cp,10);
break;
case CH_INT64:
if(!*cp) {
*(INT64 *)cp1=INT64NULL;
break;
}
*(INT64 *)cp1=strtoll(cp,&cp,10);
break;
default:
ret=0;
break;
}
return ret;
}
--
修改:ylh0315 FROM 221.221.52.*
FROM 221.221.52.*
【 在 ylh0315 的大作中提到: 】
:
: 看看它干了啥:
: int put_str_one(void *buf,char *cp,T_PkgType *typ,char CURDLM)
: ...................
这个程序的数据类型是依据数据库的,C类型只是子集。它完成了数据库类型到C类型的映射。
这里演示了一个方法,读者可以根据这个原理写自己的工具软件。
--
FROM 221.221.52.*
【 在 ziqin 的大作中提到: 】
: 最简单的办法应该是装个copilot,让copilot来写……
哦,明白了,让AI给你写,复制粘贴。
但是,有100个struct就得写200个。
用JAVAer说,就是不优雅。
--
FROM 221.221.52.*
那么,是否有可能,让AI写个我前面描述的泛型模板系统呢?包括模板生成工具。把设计思想告诉它。
【 在 ziqin 的大作中提到: 】
: 最简单的办法应该是装个copilot,让copilot来写……
--
FROM 221.221.52.*
毕竟是20年前的了,而且楼主也等不及。
介绍下你说的template,怎么描述结构成员。
【 在 z16166 的大作中提到: 】
: 您老那个C里面的反序列化的轮子,现在C++里面是现成的,就是nlohmann json里的j.template get()那种
: 等C++的反射标准搞定,这种就更好搞了
:
--
FROM 221.221.52.*
可以吧,楼主可以学习一下。
但是这个只解决json的问题。序列化还有许多不同的格式。
数据库ORM的问题还没解决。即使反射问题解决了,也解决不了数据库动态访问的问题。就是当运行时提交一个表名,就进行处理的问题。
例如,有数个类似的表,都有100多个列。
插入时需要进行去重处理。这个去重处理就是一个程序,代入哪个模板就处理哪个表。并不需要在数个类中都加入相同的处理逻辑。
【 在 z16166 的大作中提到: 】
: nlohmann json是开源的,用宏添加字段的meta信息。
: C++标准没提供反射机制的情况下,基本就这种搞法了,要不就得预处理,类似Qt、protobuf那些的meta信息处理
:
--
修改:ylh0315 FROM 221.221.52.*
FROM 221.221.52.*