免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: lxyscls
打印 上一主题 下一主题

[C] 请问如何通过结构体的基地址和偏移来操作其成员变量? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2011-11-18 10:28 |只看该作者
本帖最后由 keytounix 于 2011-11-18 13:31 编辑

1.
你这个需要考虑编译器优化时候数据的对齐问题不?
如果到这样的结构体
struct M_t
{
char a;
int b;
char *c;
}
会不会出问题?
struct M_t
{
char a;
int b;
char *c;
}__attribute__(aligned(2))
这样 属性弄一下 ,
是否会好一点呢?

2.
个人有点疑惑
既然有指针pst,还有元素m了
pst->m
不就可以弄好了吗?
如果要操作addr开始的size个单 元,
memset(addr,size,0)
不就可以了吗?

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
12 [报告]
发表于 2011-11-18 13:09 |只看该作者
本帖最后由 yulihua49 于 2011-11-18 13:34 编辑
1.
你这个要考虑过编译器优化时候数据的对齐问题没啊?
如果到这样的结构体
struct M_t
{
char a;
in ...
keytounix 发表于 2011-11-18 10:28



    提一个问题:
如果你的处理程序与结构没有定义在一起,它不知道你的结构怎么办呢?

比方写一个 struct_to_JSON(to_json,from_struct,....);
对于传进来的struct,并不知道它的具体构造,要生成一个json:
"struct_name":{"成员名1":"值1","成员名2":"值2",......}

以后人们使用这个函数:

struct_to_JSON(json,&my_struct,....);

这时才有了具体的结构。STL能做这事吗?
这我已经做成功了,你有何高招,切磋一下。

透漏一点:

int struct_to_JSON(JSON_OBJECT to_json,void *from_struct,Template *tpl,.......);
当然还可以:
int JSON_from_struct(void *to_struct,JSON_OBJECT json,Template *tpl,.....);
int struct_to_String(char *to_Str,viod *from_struct,Template *tpl,char delimit,...);
int String_to_struct(void *to_struct,char *from_Str,Template *tpl,char delimit,...);

映射数据库:
select_to_struct();
insert_from_struct();
update_from_struct(),........

论坛徽章:
0
13 [报告]
发表于 2011-11-18 13:40 |只看该作者
本帖最后由 keytounix 于 2011-11-18 13:45 编辑

回复 12# yulihua49

惭愧

JSON是啥
我刚百度了,
看了很久
没看明白
隔行如隔山啊

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
14 [报告]
发表于 2011-11-18 17:28 |只看该作者
本帖最后由 yulihua49 于 2011-11-18 17:30 编辑
回复  yulihua49

惭愧

JSON是啥
我刚百度了,
看了很久
没看明白
隔行如隔山啊
keytounix 发表于 2011-11-18 13:40



    精简的标记语言。
名-值对的数据对象。

形如:"struct_name":{"成员名1":"值1","成员名2":"值2",......}

论坛徽章:
0
15 [报告]
发表于 2011-11-18 17:40 |只看该作者
回复 14# yulihua49


    用C语言
除了宏

你能实现这个?

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
16 [报告]
发表于 2011-11-19 09:18 |只看该作者
回复  yulihua49


    用C语言
除了宏

你能实现这个?
keytounix 发表于 2011-11-18 17:40

对,已经实现了N多年了。
用模板。

另外楼上,不要把注意力放在JSON上,关键是怎么认识结构,怎么找到名字和值的位置、类型等。

论坛徽章:
0
17 [报告]
发表于 2011-11-19 16:43 |只看该作者
本帖最后由 keytounix 于 2011-11-19 16:51 编辑

回复 16# yulihua49


   我的难点在于
用C怎么得到一个结构的名称

比如
struct test
{
int a;
char b;
long c;


}

test t;
t.a=1
t.b=2;
t.c =3;

这个是事实存在的

现在我们并不知道这个test结构体

拥有哪些成员

你是怎么用C得到这个结构体的成员名呢?

还有

我是看谭好强 的C启蒙的

貌似并没看到哪里有说C的什么模版的

倒是C++里面有这个东西

如果你扯上模板了,

我是不是可以说 超出C的范围了?


你怎么知道他的成员名称?

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
18 [报告]
发表于 2011-11-19 21:02 |只看该作者
本帖最后由 yulihua49 于 2011-11-19 21:42 编辑
回复  yulihua49


   我的难点在于
用C怎么得到一个结构的名称

比如
struct test
{
int a;
ch ...
keytounix 发表于 2011-11-19 16:43



    的确,C在运行时(就不应该叫C了吧?机器码)是不知道任何结构的,只知道基地址+变址值。
就是说,C的结构,在运行时是不可解析的,在任何未定义的场合是不可能知道的。在需要进行任何内存对象的序列化和反序列化时(我的楼上例子),采用了专用的序列化和反序列化对象,如google的protobuf等等。目前没有见到对C结构进行通用的序列化和反序列化的法(大家帮我查一下,是否有)。
我们在16年前做了这个工作,并在生产环境得到大范围的应用。我一直认为,这是一个突破。

事实上,在做这个工作时,我们关心一个结构里,有多少成员,各是什么类型,多长,在哪?
此外还有各自的名字,显示的格式,其他属性。最后,这个结构总共多长(字节数)。还有,与数据库对应的表名?
哈哈,整个一个数据字典。对,就是数据字典!!!为每一个结构配一个数据字典。为了提高性能,这个数据字典用结构组的形式放在内存,这就是数据模板TEMPLATE。模板一定要C++吗?没人这么说,老谭也没说C不能做模板啊。

#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_STRUCT 125
#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

#define YEAR_TO_DAY_LEN 11
#define YEAR_TO_MIN_LEN 17
#define YEAR_TO_SEC_LEN 20
#define YEAR_TO_USEC_LEN 27

extern const char YEAR_TO_DAY[];
extern const char YEAR_TO_MIN[];
extern const char YEAR_TO_SEC[];
extern const char YEAR_TO_USEC[];
//这个就是所谓的“模板”了,它使我们能够"看"到未知结构的内容。
typedef struct {
            INT4 type;
            INT4 len; // in byte
            const char *name;
            const char *format;
            INT4 offset;
            int bindtype; //default=0
} T_PkgType;

一个T_PkgType描述了结构中的一个成员,一个完整的结构由多个T_PkgType组成,如楼主的结构配一个模板:
T_PkgType xx_tpl[]={
        {CH_INT,sizeof(int),"a",NULL,-1},
        {CH_CLOB,-1,"b"},
     {CH_CLOB,-1,"c"},
        {-1,0,"xx",0}
};

几个问题都解决了,但是位置,变量的位置在哪?offset,没有?对,这不需要你写,你也写不出来。它在运行时计算出来。

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
19 [报告]
发表于 2011-11-19 22:03 |只看该作者
本帖最后由 yulihua49 于 2011-11-19 22:09 编辑
的确,C在运行时(就不应该叫C了吧?机器码)是不知道任何结构的,只知道基地址+变址值。
就是 ...
yulihua49 发表于 2011-11-19 21:02



    我们来看一个例子,楼主的。
  1. cat xx.c
  2. #include <pack.h>
  3. #include <json_pack.h>

  4. T_PkgType xx_tpl[]={
  5.         {CH_INT,sizeof(int),"a",NULL,-1},
  6.         {CH_CLOB,-1,"b"},
  7.         {CH_CLOB,-1,"c"},
  8.         {-1,0,"xx",0}
  9. };

  10. typedef struct {
  11.         int a;
  12.         char *b;
  13.         char *c;
  14. } xx_stu;

  15. int main()
  16. {
  17. xx_stu xx;
  18. JSON_OBJECT json=json_object_new_object();

  19.         xx.a=123456;
  20.         xx.b="abcd";
  21.         xx.c="ABCD";

  22.         struct_to_json(json,&xx,xx_tpl,NULL);
  23.         printf("xx's json=xx:%s\n",
  24.                 json_object_to_json_string(json));
  25.         json_object_put(json);
  26.         return 0;
  27. }
  28. makefile:
  29. CFLAGS= -I$(SDBCDIR)/include
  30. LFLAGS= -L$(SDBCDIR)/lib

  31. xx:xx.o
  32.         cc -o xx xx.o $(LFLAGS) -lstr -ljson -lm -lpthread
  33. make
  34. cc -I/workspace/project/ticket-query/02-src/train-lines/sdbc/include   -c -o xx.o xx.c
  35. cc -o xx xx.o -L/workspace/project/ticket-query/02-src/train-lines/sdbc/lib -lstr -ljson -lm -lpthread
  36. tjs@linux:~/src> ./xx
  37. xx's json=xx:{ "a": "123456", "b": "abcd", "c": "ABCD" }

复制代码
那个struct_to_json是如何实现的?

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
20 [报告]
发表于 2011-11-19 22:40 |只看该作者
回复  yulihua49


   我的难点在于
用C怎么得到一个结构的名称

比如
struct test
{
int a;
ch ...
keytounix 发表于 2011-11-19 16:43
  1. vi xx.c
  2. #include <pack.h>
  3. #include <json_pack.h>

  4. T_PkgType xx_tpl[]={
  5.         {CH_INT,sizeof(int),"a",NULL,-1},
  6.         {CH_CLOB,-1,"b"},
  7.         {CH_CLOB,-1,"c"},
  8.         {-1,0,"xx",0}
  9. };

  10. typedef struct {
  11.         int a;
  12.         char *b;
  13.         char *c;
  14. } xx_stu;

  15. int main()
  16. {
  17. xx_stu xx;
  18. JSON_OBJECT json=json_object_new_object();
  19. T_PkgType *tp;

  20.         xx.a=123456;
  21.         xx.b="abcd";
  22.         xx.c="ABCD";

  23.         struct_to_json(json,&xx,xx_tpl,NULL);
  24.         printf("xx:%s\n",
  25.                 json_object_to_json_string(json));
  26.         json_object_put(json);
  27.         for(tp=xx_tpl;tp->type>-1;tp++)
  28.                 printf("%s offset=%d,",tp->name,tp->offset);
  29.         printf("\nsizeof xx=%d\n",tp->offset);
  30.         return 0;
  31. }
  32. "xx.c" 35L, 617C 已写入                                                
  33. tjs@linux:~/src> make xx
  34. cc -I/workspace/project/ticket-query/02-src/train-lines/sdbc/include   -c -o xx.o xx.c
  35. cc -o xx xx.o -L/workspace/project/ticket-query/02-src/train-lines/sdbc/lib -lstr -ljson -lm -lpthread
  36. tjs@linux:~/src> ./xx
  37. xx:{ "a": "123456", "b": "abcd", "c": "ABCD" }
  38. a offset=0,b offset=4,c offset=8,
  39. sizeof xx=12
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP