- 主题:C可以做泛型吗?
对,需要一个参数表。一个通用的参数表。如果有反射,这个参数表就可以通过反射取得。否则就得自己想办法弄这个参数表。
【 在 hehao 的大作中提到: 】
: 真实数据访问实现中要考虑了类型的对齐,大小
: addr, [<type, align, size>, ...]
: 把这些信息和内存地址作为参数传入,应该就能实现你需要的能力
: ...................
--
FROM 221.221.50.*
可以用JSON格式解决这个问题。但是,JSON与struct的结合还是需要反射,或者参数表。
【 在 freyoneby 的大作中提到: 】
: 其他语言就可以了?
: - 来自 水木社区APP v3.5.7
--
FROM 221.221.50.*
在项目内部实现一个lisp就行,lua也可以
【 在 ylh1969 的大作中提到: 】
:
: 如果写一个通用的序列化程序,接受一个struct指针。
: 通用,即任意的struct,写程序的时候,并不知道是什么struct,只能用void *。
: 【 在 freyoneby 的大作中提到: 】
: : C语言不知道struct的信息?你是指只生声明了一个指针?还是不懂,有来段简单代码
#发自zSMTH@23054RA19C
--
FROM 113.143.107.*
做了一个通用的。
泛型是个全新的世界,除了序列化反序列化,更重要的是做SQL,通用的SQL映射框架(可以认为是广义的序列化反序列化),如JAVA的hibernate。
把struct,模板,sql句柄,游标整合成DAU,Data Access Unit。
就可以简单高效的访问数据库啦!
然后,数据可以在服务器客户端间方便的传输(序列化反序列化,用同一个struct模板)。
模板,就是你那个list,可以用数据库的表结构自动生成。几十上百列的庞杂结构用起来就很方便了。
如果业务需要改变表结构,还可以自适应。这才是泛型程序的优势所在。
【 在 VincentGe 的大作中提到: 】
: 在项目内部实现一个lisp就行,lua也可以
:
: #发自zSMTH@23054RA19C
--
修改:ylh1969 FROM 221.221.50.*
FROM 221.221.50.*
难点是计算offset。
struct的offset比较好算,class的,我不会算,只能等着反射来解决了。
效率问题,计算一次即可,之后的使用就不必算了。
【 在 VincentGe 的大作中提到: 】
: 在项目内部实现一个lisp就行,lua也可以
:
: #发自zSMTH@23054RA19C
--
修改:ylh1969 FROM 221.221.50.*
FROM 221.221.50.*
下边的,data就是未知的struct,模板是typ,choose是可以选择部分成员序列化,colidx是索引,可以较快的找到名字,没有也行,在模板里顺序查找呗。
序列化到json里。
【 在 freyoneby 的大作中提到: 】
: C语言不知道struct的信息?你是指只生声明了一个指针?还是不懂,有来段简单代码
: - 来自 水木社区APP v3.5.7
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
tp=typ;
if(!choose||!*choose) { // 没有选择,全部加入
for(i=0;tp->type>=0;i++,tp++) {
if(tp->bindtype & NOSELECT) continue;//不想要的成员也可以在此剔除
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);//把这个成员加到JSON里
}
return json;
--
修改:ylh1969 FROM 221.221.50.*
FROM 221.221.50.*
数据的反射信息在c里也可以生成,
做一个解析器,或者手动完成,对代码中的结构体定义
struct {
int a;
char b;
} dummy_t;
根据上下文的对齐规则和数据大小规则,生成类似这个结构
meta meta_dummy_t[3]={ TYPE_INT, ALIGN_4, SIZE_4, MD5_NAME(a),
TYPE_CHAR, ALIGN_4, SIZE_4,MD5_NAME(b),
NULL, NULL, NULL,MD%_NAME(0)};
在发生数据交互时,可以交互这个数据的元数据
(dummy_t*)get_data
(meta*)get_data_meta
跨平台使用是个麻烦,打包int是按照4字节打包,假如目标只接受
8字节对齐int数据访问;这时候需要根据获取的meta_dummy_t改造
当前平台的数据结构布局,并实现赋值;还有一个要注意的是在不同
大小端架构上交换位域数据结构体时顺序也是要转换的
【 在 ylh1969 的大作中提到: 】
: 难点是计算offset。
: struct的offset比较好算,class的,我不会算,只能等着反射来解决了。
: 效率问题,计算一次即可,之后的使用就不必算了。
: ...................
--
FROM 120.231.170.*
必须跨平台呀。客户端服务器不一定是一个平台。
好像缺了一个FLOAT的,这个类型一直没用过,加上也不难。
【 在 hehao 的大作中提到: 】
: 数据的反射信息在c里也可以生成,
: 做一个解析器,或者手动完成,对代码中的结构体定义
: struct {
: ...................
#define M_ST_OFF(struct_type, member) \
(int)((long)(void *) &(((struct_type*) 0)->member))
//这些结构用来测试各种数据的边界对齐规则,不要猜,要让编译器自己说。
typedef struct {
char a;
int b;
} align;
typedef struct {
char a;
double b;
} dalign;
typedef struct {
char a;
long double b;
} dfali;
typedef struct {
char a;
INT63+1 b;
} ll_ali;
typedef struct {
char a;
long b;
} l_ali;
。。。。。
int set_offset(T_PkgType *pkg_type)
{
int i,k,l;
int ali,dali,lali,llali,ldli;
int max_align=1;
if(!pkg_type) return -1;
if(pkg_type->offset>-1) return cnt_type(pkg_type);
ali= M_ST_OFF(align,b) - 1;
dali=M_ST_OFF(dalign,b) - 1;
lali= M_ST_OFF(l_ali,b) - 1;
llali= M_ST_OFF(ll_ali,b) - 1;
ldli= M_ST_OFF(dfali,b) - 1;
--
修改:ylh1969 FROM 221.221.50.*
FROM 221.221.50.*
模板可以手写,也可以用数据库表结构自动生成,还可以用元数据生成模板和结构。
客户端服务器用相同的模板就可以,边界对齐,大小端的问题,运行时解决。
在set_offset()里处理。https://
www.newsmth.net/nForum/#!article/CPlusPlus/423333?p=3
从20楼往后看,
【 在 hehao 的大作中提到: 】
: 数据的反射信息在c里也可以生成,
: 做一个解析器,或者手动完成,对代码中的结构体定义
: struct {
: ...................
--
修改:ylh1969 FROM 221.221.50.*
FROM 221.221.50.*
直接用c++ 有什么不妥吗?
--
FROM 222.129.5.*