- 论坛徽章:
- 15
|
本帖最后由 yulihua49 于 2010-05-04 17:07 编辑
typedef struct
{
char a;
short b;
int c;
} B;
这个short不是紧接着char a 后面的, ...
deanshuai 发表于 2010-04-26 21:01 ![]()
32位linux的double是4字节对齐,64位是8字节对齐。
给你一个边界对齐的计算程序:这个程序用于分析未知结构的成员,数量类型,长度,位置(边界对齐),格式和整个结构的尺寸。
- #include <pack.h>
- #define M_ST_OFF(struct_type, member) \
- (int)((void *) &(((struct_type*) 0)->member))
- //这些结构用来测试各种数据的边界对齐规则,不要猜,要让编译器自己说。
- typedef struct {
- char a;
- long b;
- } align;
- typedef struct {
- char a;
- double b;
- } dalign;
- typedef struct {
- char a;
- long double b;
- } dfali;
- typedef struct {
- char a;
- INT64 b;
- } lfali;
- int set_offset(T_PkgType *pkg_type)
- {
- int i,k;
- int ali,dali,lali,ldli;
- int max_allign=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(lfali,b) - 1;
- ldli= M_ST_OFF(dfali,b) - 1;
- k=0;
- for(i=0;pkg_type[i].type>-1;i++){
- pkg_type[i].offset=k;
- pkg_type[i].bindtype=0;
- if((pkg_type[i].type&127)!=CH_CLOB)k+=pkg_type[i].len;
- else k+=sizeof(char *);
- switch(pkg_type[i+1].type&127) {
- case 127:
- case CH_CHAR:
- case CH_BYTE:
- case CH_TINY:
- break;
- case CH_INT64:
- k=(k+lali)&~lali;
- max_allign=(max_allign>sizeof(INT64))?max_allign:sizeof(INT64);
- break;
- case CH_LDOUBLE:
- k=(k+ldli)&~ldli;
- break;
- case CH_DOUBLE:
- k=(k+dali)&~dali;
- max_allign=(max_allign>sizeof(double))?max_allign:sizeof(double);
- break;
- case CH_SHORT:
- k=(k+1)&~1;
- max_allign=(max_allign>sizeof(short))?max_allign:sizeof(short);
- break;
- case CH_CLOB:
- k=(k+(sizeof(char *)-1)) & ~(sizeof(char *)-1);
- max_allign=(max_allign>sizeof(char *))?max_allign:sizeof(char *);
- break;
- case CH_FLOAT:
- case CH_INT:
- k=(k+3)&~3;
- max_allign=(max_allign>sizeof(int))?max_allign:sizeof(int);
- break;
- case CH_LONG:
- max_allign=(max_allign>sizeof(long))?max_allign:sizeof(long);
- default:
- k=(k+ali)&~ali;
- break;
- }
- }
- // 2009-06-22 by ylh,adjuct to struct align
- // pkg_type[i].offset=(k+ali)&~ali;
- if(max_allign>1) {
- max_allign--;
- pkg_type[i].offset=(k+max_allign)&~max_allign;
- }
- pkg_type[i].bindtype=0;
- return i;
- }
- pack.h的部分内容:
- #include <sys/types.h>
- #include <datejul.h>
- #define CH_BYTE 0
- #define CH_CHAR 1
- #define CH_TINY 2
- #define CH_SHORT 3
- #define CH_INT 4
- #define CH_LONG 5
- #define CH_INT64 6
- #define CH_FLOAT 7
- #define CH_DOUBLE 8
- #define CH_LDOUBLE 9
- #define CH_CLOB 126
- extern const char NAN[sizeof(double)];
- #define DOUBLENULL (*(double *)NAN)
- #define FLOATNULL (*(float *)NAN)
- #define SHORTNULL (short)(1<<(8*sizeof(short)-1))
- #define INTNULL (int)(1<<(8*sizeof(int)-1))
- #define LONGNULL (1L<<(8*sizeof(long)-1))
- #define INT64NULL ((INT64)1<<(8*sizeof(INT64)-1))
- #define TINYNULL 0X80
- /*****************************************************
- * define extend data type for net_pack()
- *****************************************************/
- #define CH_DATE CH_CHAR|0x80
- #define CH_CNUM CH_CHAR|0x100
- #define CH_JUL CH_INT4|0X80
- #define CH_MINUTS CH_INT4|0x100
- #define CH_TIME CH_INT64|0x80
- #define CH_USEC CH_INT64|0x200
- /* used by varchar2 as date(year to day),default format is "YYYYMMDD" */
- #define CH_CJUL CH_INT4|0x200
- #define CH_CMINUTS CH_INT4|0x400
- /* used by varchar2 as date(year to sec),default format is "YYYYMMDDHH24MISS" */
- #define CH_CTIME CH_INT64|0x100
- //这个就是所谓的“模板”了,它使我们能够"看"到未知结构的内容。
- typedef struct {
- INT4 type;
- INT4 len; // in byte
- char *name;
- const char *format;
- INT4 offset;
- int bindtype; //default=0
- } T_PkgType;
- // for bindtype
- #define RETURNING 1 //this column only for returnning
- #define NOINS 2 //this column don't insert or update
- #define NOSELECT 4 //this column don't select only used by bind
复制代码 以上就是 结构-关系映像(SRM,Struct Relational mapping) 最核心的内容。SRM完成把结构的内容与字符串互相映像(结构变字符串,也叫序列化,字符串变结构,也叫反序列化;
结构内容进入数据库表,数据库表的内容进入结构;JSON与结构的互相映射等等。 |
|