我有两个库,不幸的是它们定义了两个相同的预处理器定义(我需要使用它):
lib1.h
#define MYINT 1
lib2.h
#define MYINT 2
在我的程序中,我需要使用它们:
#include <Lib1.h>
#include <lib2.h>
...
int myint = MYINT;
在这里我有错误,MYINT无法解决。
当我无法修改lib文件时,如何解决这个问题?
你可能之前#undef MYINT
包括标题作为解决方法。
#undef MYINT
#include <Lib1.h>
const int myint_lib1 = MYINT; // 1
#undef MYINT
#include <lib2.h>
const int myint_lib2 = MYINT; // 2
在第二个库替换它之前获取第一个库的MYINT
值。
#include <Lib1.h>
int myInt1 = MYINT;
#undef MYINT
#include <lib2.h>
int myInt2 = MYINT;
#undef MYINT
当然,如果MYINT
是动态的东西并且您需要保持其实际内容,那么这不起作用。
由handy999编辑:在预处理器语句结束时没有分号。
没有预处理器技巧:
lib1_handler.h
extern int lib1_handler_myint;
// or
int lib1_handler_myint_f();
lib1_handler.c
#include <Lib1.h>
int lib1_handler_myint = MYINT;
// or
int lib1_handler_myint_f() { return MYINT; }
lib2_handler.h
extern int lib2_handler_myint;
// or
int lib1_handler_myint_f();
lib2_handler.c
#include <Lib2.h>
int lib2_handler_myint = MYINT;
// or
int lib2_handler_myint_f() { return MYINT; }
main.c中
#include "lib1_handler.h"
#include "lib2_handler.h"
int void () {
return lib1_handler_myint || lib2_handler_myint_f();
}
我将采用的方法是从每个包含文件中派生一个包含文件的扩展版本,它将通过包含文件本身之外的不同机制提供MYINT
。
因此,从lib1.h
创建一个名为lib1_ext.h
的包含文件,其中包含以下行:
#if !defined(MYLIB1_EXT_H_INCLUDED)
#define MYLIB1_EXT_H_INCLUDED
// ensure that MYINT is not defined no matter what order the include files are used
#undef MYINT
#include "lib1.h"
const int myInt_lib1 = MYINT; // make a copy of the value of MYINT if it is needed
// make sure MYINT is undefined to allow the compiler to catch any dependencies on it
#undef MYINT
#endif
并且类似地为lib2.h
创建lib2_ext.h
,如:
#if !defined(MYLIB2_EXT_H_INCLUDED)
#define MYLIB2_EXT_H_INCLUDED
// ensure that MYINT is not defined no matter what order the include files are used
#undef MYINT
#include "lib2.h"
const int myInt_lib2 = MYINT; // make a copy of the value of MYINT if it is needed
// make sure MYINT is undefined to allow the compiler to catch any dependencies on it
#undef MYINT
#endif
现在当使用库的任何功能时,使用MYINT
值的相应副本,myInt_lib1
在使用lib1.h
功能和/或myInt_lib2
时使用lib2.h
功能。但是,如果MYINT
仅与库头文件本身一起使用,并且在任何地方都不需要实际使用该库,那么您可以放弃该语句。
另请参阅Can I redefine a C++ macro then define it back?,其中显示了如何使用某些供应商的编译器和pragma
指令保存和恢复宏定义。但是,这似乎并不适用于您的发布。
该帖子还有一个答案,它描述了宏扩展的基础知识,以及为什么需要const int myInt_lib1 = MYINT;
来保存MYINT
的值而不是像#define MYINT_LIB1 MYINT
那样使用预处理器来保存MYINT
的值。预处理器尽可能地延迟宏的扩展,结果是,一旦使用#define MYINT_LIB1 MYINT
指令未定义MYINT
,尝试使用MYINT
中的预处理器宏来保存#undef
的值不起作用。当预处理器首先用文本MYINT_LIB1
替换文本MYINT
然后进行重新扫描时,由于MYINT
现在未定义,文本MYINT
仍然存在,如果幸运的话,结果是编译器错误。
这项工作需要考虑的一件事
这项工作假设所需要的只是MYINT
的数值,它被视为int
常数值。因此,它假设使用MYINT
的地方也可以使用const int
。
这意味着任何类型的令牌粘贴,#if
测试或其他预处理器操作涉及处理MYINT
被定义为可由预处理器用于其他宏操作的文本的文本在lib.h
之外的地方不能正常工作或lib2.h
包含在预处理器中并由其处理。
它还意味着您无法指定编译器选项来将MYINT
声明为条件编译的一部分,因为编译器选项创建的宏将被忽略并通过此解决方案消除。
因此,预处理器生成的源对MYINT
作为每个包含文件之外的文本宏的依赖性将导致编译中断。
可能的依赖关系的一个例子是lib1.h
中的一个宏,它使用MYINT
为函数创建一个额外的,看不见的参数,如:
int funcStuff (int a, struct b *pBthing);
#define FUNCSTUFF (pBthing) funcStuff(MYINT, (pBthing))
期望任何使用该库的人都会使用FUNCSTUFF(&bThing);
而不是funcStuff (MYINT, &bThing);
。为了完成这项工作,您需要直接使用funcStuff()
中的funcStuff(myInt_lib1, &bThing);
函数,或者使用FUNCSTUFF()
而不是myInt_lib1
创建自己的MYINT
宏。