ImageVerifierCode 换一换
格式:DOC , 页数:12 ,大小:123.50KB ,
资源ID:7041856      下载积分:10 金币
验证码下载
登录下载
邮箱/手机:
图形码:
验证码: 获取验证码
温馨提示:
支付成功后,系统会自动生成账号(用户名为邮箱或者手机号,密码是验证码),方便下次登录下载和查询订单;
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/7041856.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请。


权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4009-655-100;投诉/维权电话:18658249818。

注意事项

本文(程序App链接B库时如何解决枚举值不匹配.doc)为本站上传会员【xrp****65】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

程序App链接B库时如何解决枚举值不匹配.doc

1、情况是这样的: App程序只提供了部分代码,B库有全部代码。 B库的代码需要用到App里面定义的一些枚举量,现在需要将B库链接到App里。 由于枚举量的定义中使用了编译开关来控制,而App具体打开了哪些开关未知,从而导致B库中如果直接#include App使用的头文件所得到的枚举值与App里面运行时所得到的枚举值不匹配。 还是写个Demo程序来说吧,App的代码是这样的,首先是App.h这个双方都要用的头文件如下: #ifndef APP_H #define APP_H /* Value of ID_E is controlled by switch SWITCH_ID

2、CD If SWITCH_ID_CD is enabled, ID_E = 4, If SWITCH_ID_CD is disabled, ID_E = 2. */ typedef enum t_ID{ ID_A = 0, ID_B, #ifdef SWITCH_ID_CD ID_C, ID_D, #endif ID_E, ID_F }ID; #endif 可以看到如果编译开关 SWITCH_ID_CD 打开,则 ID_E = 4,否则 ID_E = 2。 BLib 的代码 BLib.c

3、如下: #define BLIB_C /* App.h is from App, and we have no idea of SWITCH_ID_CD is switched on or off */ #include "../App/App.h" /* Get value of id */ int get_id_value(ID id){ return (int)id; } /* It will return 2 because SWITCH_ID_CD not defined in this lib */ int get_ID_E(){

4、 return get_id_value(ID_E); } BLib.c 并没有打开编译开关 SWITCH_ID_CD,那么当App调用BLib的函数 get_ID_E() 时,将会返回2。 App的主程序App.c如下: /* Link BLib.lib in App */ #pragma comment(lib, "../Debug/BLib.lib") /* We switch on SWITCH_ID_CD in App, and disable it in BLib.lib */ #define SWITCH_ID_CD #include "std

5、io.h" #include "App.h" /* Functions from BLib.lib */ extern int get_id_value(ID id); extern int get_ID_E(); int main(int argc, char* argv[]) { printf("\n----- In App -----\n"); printf("ID_E = %d.\n", (int)ID_E); // 此处会返回4 printf("\n----- In BLib.lib ----

6、\n"); printf("ID_E = %d. (call get_ID_E())\n", get_ID_E()); // 此处会返回2 getchar(); return 0; } App.c 打开了编译开关 SWITCH_ID_CD,所以当App显示ID_E的值时,将会返回4。 运行的结果也验证了这一点。 ----- In App ----- ID_E = 4. ----- In BLib.lib ----- ID_E = 2. (call get_ID_E()) 上面的不匹配就是遇到的问题,怎么解决它呢?曾经考虑过几个方案

7、 方案1:直接Hack出枚举值的数值,然后在BLib.c中使用之 方案2:使用字符串到数值的译码方式匹配枚举值 方案3:使用extern方式引用外部变量   下面分别论述其可行性。 方案1:直接Hack出枚举值的数值,然后在BLib.c中使用之 这种方法最简单粗暴,既然无法确认App使用了哪些编译开关,那就通过debug的方式将App.h中定义的枚举量的具体数值直接打印出来,然后在BLib.c中使用。 但是这种硬编码的方式其扩展性也最差,一旦App的编译开关发生变化,其枚举量势必会跟着变化,这时再手工修改BLib.c就成了苦差事。 本方法仅适合于快速调试等短线投资,不适合长

8、线持有。   方案2:使用字符串到数值的译码方式匹配枚举值 这种方法实现方式就是在BLib.c里新建一个函数,向其传入“ID_E”这个字符串,然后该函数调用App里面的解析函数,将这个字符串匹配到实际的ID_E的数值并返回。 听上去稍微优雅一些,但是问题也不少,比方说对于这些字符串的解析过程,将来枚举量增加的话(目前项目的枚举量在上千个左右),还用一堆的if else来线性挨个比较显然效率不高,可如果用HashTable做快速映射则势必增加代码量,更别说存储这些字符串及哈希值需要占用的存储空间了。   方案3:使用extern方式引用外部变量 考虑再三,要想节省存储空间,又要能够

9、对不同的编译开关产生的枚举值做出适配,用extern方式引用外部变量是个方法,修改代码如下。 新增头文件 ForBLib.h 如下: /* Declare and init in App.c, and extern in BLib */ #ifdef APP #define GLOBAL #else #define GLOBAL extern #endif /* Declare needed enum, e.g. LIB_ID_E */ GLOBAL int LIB_ID_E; 当App.c插入此头文件时,宏 GLOBAL 的定义为空,即为声

10、明 LIB_ID_E 变量,而当BLib.c插入此头文件时,宏 GLOBAL 的定义为 extern,即为引用外部变量。 BLib.c 修改代码如下: #define BLIB /* App.h is from App, and we have no idea of SWITCH_ID_CD is switched on or off */ #include "../App/App.h" #include "../App/ForBLib.h" /* Get value of id */ int get_id_value(ID id){ return (int

11、)id; } /* It will return 2 because SWITCH_ID_CD not defined in this lib */ int get_ID_E(){ return get_id_value(ID_E); } /* It will return 4 if LIB_ID_E is init as ID_E in App.c, or return 0 if not */ int get_LIB_ID_E(){ return get_id_value(LIB_ID_E); } 在BLib.c中定义了宏 BLIB,用于在插入

12、 ForLibB.h 时识别。 App.c 修改代码如下: #define APP /* Link BLib.lib in App */ #pragma comment(lib, "../Debug/BLib.lib") /* We switch on SWITCH_ID_CD in App, and disable it in BLib.lib */ #define SWITCH_ID_CD #include "stdio.h" #include "App.h" #include "ForBLib.h" /* Functions from BLib.l

13、ib */ extern int get_id_value(ID id); extern int get_ID_E(); extern int get_LIB_ID_E(); /* Init LIB_ID_X, e.g. LIB_ID_E = ID_E */ void init_LIB_ID(){ LIB_ID_E = ID_E; } int main(int argc, char* argv[]) { printf("\n----- In App -----\n"); printf("ID_E = %d.\n", (int)ID_E);

14、 // 此处会返回4 printf("\n----- In BLib.lib and did not run init_LIB_ID() -----\n");// 此时暂未调用 init_LIB_ID() printf("ID_E = %d. (call get_ID_E())\n", get_ID_E()); // 此处会返回2 printf("LIB_ID_E = %d. (call get_LIB_ID_E())\n", get_LIB_ID_E()); // 此

15、处会返回0,因为 LIB_ID_E 未初始化,被编译器自动初始化为0 printf("\n----- In BLib.lib and run init_LIB_ID() -----\n"); init_LIB_ID(); // 此时调用 init_LIB_ID(),LIB_ID_E = ID_E printf("ID_E = %d. (call get_ID_E())\n", get_ID_E()); // 此处仍然返回2

16、 printf("LIB_ID_E = %d. (call get_LIB_ID_E())\n", get_LIB_ID_E()); // 此处会返回4,这就OK了 getchar(); return 0; } 在App.c中定义了宏 APP,同样用于在插入 ForLibB.h 时识别。 运行的结果如下: ----- In App ----- ID_E = 4. ----- In BLib.lib and did not run init_LIB_ID() ----- ID_E = 2. (call get_ID_E()) LIB_ID

17、E = 0. (call get_LIB_ID_E()) ----- In BLib.lib and run init_LIB_ID() ----- ID_E = 2. (call get_ID_E()) LIB_ID_E = 4. (call get_LIB_ID_E()) 可见,只要先对变量 LIB_ID_E 进行初始化,则 BLib.c 中使用 LIB_ID_E 就等同于使用 ID_E 了。 但是,如果需要用到的枚举量增加,如成百上千个,手工写代码就成了一件苦事,能否通过宏来设计一套机制,只需要更改一处,两边都可以达到升级的目的?   3.1 利用宏+extern

18、一次修改,两边运行 增加一个辅助头文件BLibHelper.h如下: #ifndef FORBLIB_H #define FORBLIB_H /* Declared when use in App.c */ #ifdef APP #define GLOBAL #else #define GLOBAL extern #endif /* ID_E -> LIB_ID_E */ #define GET_LIB_ID(ID_NAME) LIB_##ID_NAME /* ID_E -> extern int LIB_ID_E */ #defi

19、ne DECLARE_LIB_ID(ID_NAME) GLOBAL int GET_LIB_ID(ID_NAME) /* ID_E -> LIB_ID_E = (int)ID_E */ #define INIT_LIB_ID(ID_NAME) GET_LIB_ID(ID_NAME) = (int)ID_NAME /* Declare and init in App.c */ #include "ForBLib.h" #endif GLOBAL的用法上面已经说过,GET_LIB_ID的用法需要讲讲。 举例来说,代码中的 GET_LIB_ID(ID_E) 会被编译器在

20、预编译阶段展开为 LIB_ID_E,宏代码中的"##"等同于连接左右两端的字符串。 同理,代码中的 DECLARE_LIB_ID(GET_LIB_ID(ID_E)) 会被展开为两个不同的形式,当在App.c中使用时,展开为 int LIB_ID_E,而在BLib.c中使用时,则为 extern int LIB_ID_E 同理,代码中的 INIT_LIB_ID(GET_LIB_ID(ID_E)) 会被展开为 LIB_ID_E  = (int)ID_E 在这个头文件的最后,插入了 ForBLib.h 文件,这个文件与之前的文件变化很大,如下: /* Declare and init i

21、n App.c, and extern in BLib */ #ifdef APP #define OPERATE_LIB_ID INIT_LIB_ID #else #define OPERATE_LIB_ID DECLARE_LIB_ID #endif /* Declare needed enum, e.g. LIB_ID_E */ OPERATE_LIB_ID(ID_E); OPERATE_LIB_ID(ID_F); 该文件引用了两个枚举量ID_E和ID_F。 如果该文件被App.c插入,其展开就是对下面出现的枚举量初始化,而如果被BLib.c插入,就成

22、了对它们的声明。 现在BLib.c的文件修改如下: #define BLIB /* App.h is from App, and we have no idea of SWITCH_ID_CD is switched on or off */ #include "../App/App.h" #include "../App/BLibHelper.h" /* Get value of id */ int get_id_value(ID id){ return (int)id; } /* It will return 2 because SWITCH_I

23、D_CD not defined in this lib */ int get_ID_E(){ return get_id_value(ID_E); } /* It will return 4 if LIB_ID_E is init as ID_E in App.c, or return 0 if not */ int get_LIB_ID_E(){ return get_id_value(GET_LIB_ID(ID_E)); } /* It will return 5 if LIB_ID_F is init as ID_F in App.c, or r

24、eturn 0 if not */ int get_LIB_ID_F(){ return get_id_value(GET_LIB_ID(ID_F)); } 可以看到,它只需要插入BLibHelper.h即可。 在BLib.c中,需要使用到ID_E正确的值,只需要调用 GET_LIB_ID(ID_E) 即可,因为这只是一个预编译阶段的宏展开,所以比方案2中的查表匹配效率高。 App.c的代码修改为: #define APP /* Link BLib.lib in App */ #pragma comment(lib, "../Debug/BLib.lib"

25、) /* We switch on SWITCH_ID_CD in App, and disable it in BLib.lib */ #define SWITCH_ID_CD #include "stdio.h" #include "App.h" #include "BLibHelper.h" /* Functions from BLib.lib */ extern int get_id_value(ID id); extern int get_ID_E(); extern int get_LIB_ID_E(); /* Init LIB_ID_X, e.

26、g. LIB_ID_E = ID_E */ void init_LIB_ID(){ #include "ForBLib.h" // 初始化变量 } int main(int argc, char* argv[]) { printf("\n----- In App -----\n"); printf("ID_E = %d.\n", (int)ID_E); // 此处会返回4 pr

27、intf("\n----- In BLib.lib and did not run init_LIB_ID() -----\n");// 此时暂未调用 init_LIB_ID() printf("ID_E = %d. (call get_ID_E())\n", get_ID_E()); // 此处会返回2 printf("LIB_ID_E = %d. (call get_LIB_ID_E())\n", get_LIB_ID_E()); // 此处会返回0,因为 LIB_ID_E 未初始化,被编译器自动初始化为0 printf("\n

28、 In BLib.lib and run init_LIB_ID() -----\n"); init_LIB_ID(); // 此时调用 init_LIB_ID(),LIB_ID_E = ID_E printf("ID_E = %d. (call get_ID_E())\n", get_ID_E()); // 此处仍然返回2 printf("LIB_ID_E = %d. (call get_LIB_ID_E())\n",

29、 get_LIB_ID_E()); // 此处会返回4,这就OK了 printf("LIB_ID_F = %d. (call get_LIB_ID_F())\n", get_LIB_ID_F()); // 此处会返回5,这就OK了 getchar(); return 0; } 文件中 init_LIB_ID() 的内容很简单,就是插入 ForBLib.h。 运行结果如下: ----- In App ----- ID_E = 4. ----- In BLib.lib and did not run init_LIB_ID() --

30、 ID_E = 2. (call get_ID_E()) LIB_ID_E = 4. (call get_LIB_ID_E()) ----- In BLib.lib and run init_LIB_ID() ----- ID_E = 2. (call get_ID_E()) LIB_ID_E = 4. (call get_LIB_ID_E()) LIB_ID_F = 5. (call get_LIB_ID_F()) 如果需要增加枚举量,只需要修改 ForBLib.h 即可,如: ... OPERATE_LIB_ID(ID_E); OPERATE_LIB_ID

31、ID_F); // 此处增加新枚举量,如 // OPERATE_LIB_ID(ID_G); 之所以在定义 LIB_ID_E 时类型为 int 而不是 ID,是因为枚举值可以轻易的转为 int 值,这样在增加不同类型的枚举量时不用考虑类型不一致了。 附上方案3.1的VC2010版本例子代码,在这里。需要注意的是App和BLib都是选择“Compile As C Code”   综上所述,使用方案3.1还是较为简单粗暴的: - App.c 和 BLib.c 都插入 BLibHelper.h 这个头文件,App.c中加入一个 init_LIB_ID() 的函数,内容只有一句 #inc

32、lude "ForBLib.h"。 - BLib.c 中使用 ID_E 这样的枚举量时,使用 GET_LIB_ID(ID_E) 的方式。 - 需要增加枚举量X时,就在 ForBLib.h 后面增加 OPERATE_LIB_ID(X);   题外话,如果要提高App的可移植性,最好还是将App.h中的枚举量如下挨个硬编码出确定数值,这样就不需要担心被编译开关打断了。 typedef enum t_ID{ ID_A = 0, ID_B = 1, #ifdef SWITCH_ID_CD ID_C = 2, ID_D = 3, #endif ID_E = 4, ID_F = 5 }ID; 爱生活,爱拉风

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服