如何"disable"从 C 标头导入的宏
How to "disable" macros imported from C-Header
类A使用用C编写的库。该库提供了一些在a中使用的数据类型和常量。不幸的是,该库还在其头文件中定义了宏,这些宏与我在main.cpp中的c++代码或使用a的其他类中的宏发生冲突。
当A.h包含在某个地方时,我如何防止c_library.h的宏被执行?我也会对体系结构的变化持开放态度,但我宁愿不碰C库。
当然,还有#undef指令。但这意味着每个宏或每个碰撞都需要大量的手工工作。(好吧,没有太多-但是,嘿,这一定可能更优雅?)
代码://main.cpp
#include "A.h"
...
A a(...)
...
std::max(x, y); // oops, problem since max is defined as macro in c_library.h
...
//A.h
#include "c_library.h"
class A{
public:
A(...);
static void callbackForCLibrary(datatypeOfCLibrary d){...}
private:
private datatypeOfCLibrary1;
private datatypeOfCLibrary2;
}
您已经知道#undef
选项,它可以满足您的需求。
但是还有另一种选择。您可以对用户完全隐藏A
使用库C
的事实:在A
的头和类定义中定义您自己的类型和接口,并从A
头中删除库包含。然后在您的实现文件中,您可以包括库头并以任何需要的方式利用库,同时对用户隐藏c_library.h
的包含。这样做的额外好处是减少了类用户、类和它所依赖的库之间的耦合。
您可以创建一个"wrap_c_library.h",类似于:
#ifndef WRAP_C_LIBRARY_H
#define WRAP_C_LIBRARY_H
#include "c_library.h"
#undef TROUBLESOME_MACRO_FROM_C_LIBRARY
#endif // WRAP_C_LIBRARY_H
可能(不确定这在实践中会有多好)#undef
不一定意味着手工工作-您可以自动生成第二个文件,以包含#undef
从第一个头文件中的所有定义。
。
#define A(X, Y) [X ; Y]
#define B(X, Y) {X...Y}
#define C this is C
#define D this is D
…运行以下短脚本:
gcc -undef -dN -E foo.h > undef_foo.h
sed -i ".bak" 's/#define[ t]([A-Za-z0-9_]*)/#undef 1/g' undef_foo.h
gcc -undef -dD -E - < /dev/null >> undef_foo.h
sed -i ".bak" '/#[du]/!d' undef_foo.h
…生成这个报头:
#undef __STDC__
#undef __STDC_HOSTED__
#undef __DYNAMIC__
#undef A
#undef B
#undef C
#undef D
#define __STDC__ 1
#define __STDC_HOSTED__ 1
#define __DYNAMIC__ 1
基本思想:获得包含foo.h
的所有定义的列表。GCC的-undef -dN
参数最小化了将包含在此列表中的系统提供的内容的数量(对我来说减少到三个,不确定这是否一致),以最小化附带内容并简化输出。然后将所有#define
行替换为等效的#undef
行(-dN
通过不列出替换项使这更容易)。然后将GCC仍然包含的几个系统定义的宏附加到文件末尾,这样它们的值就会恢复。最后,从文件中删除所有不是#define
或#undef
的指令。
用法:
#include "foo.h"
#include "undef_foo.h"
A(1, 2)
B(3, 4)
C
D
运行gcc -E
,观察宏没有展开。
有更好的脚本技能的人可能会做得更好,但这是基本的想法。
您可以使用#ifdef
和#undef
预处理器指令来检测您想在c++中调用的函数,并禁用C头文件
1)对于任何特定的宏,您可以使用#undef
"禁用"它。
2)如果你不想要任何定义从一个特定的头:只是不要#include
它。
3)如果头被其他内容隐式包含,并且您仍然希望"禁用"整个头,那么您可以在第一次包含前#define
头保护。
4)我无法想象这些选项会适用于"std::max()":
http://en.cppreference.com/w/cpp/algorithm/max另一种方法是在麻烦的文件"DO_NOT_DEFINE_MACROS"中添加一个新的宏开关
修改有问题的文件,如果定义了宏,则不定义宏,
在包含它之前,定义宏,包含文件,然后取消宏。
- 尝试导入pybind-opencv模块时出现libgtk错误
- 导入库可以跨dll版本工作吗
- 建议在运行时将带有类实例的列表从c++导入qml
- 导入/导出变量时出错
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- 将QT项目导入Visual Studio 2019会给我带来很多LNK2001错误
- 是否可以将函数导入命名空间,但不能导出它?
- 如何将 CLion C++ 项目导入 Visual Studio?
- Python 3.8 不能与 Pybind11 一起导入 [Windows]
- 无法将标准库导入本机 android 项目中的头文件
- 尝试了解在导入的静态方法上使用删除方法时的错误
- 在 python 模块中导入子模块时PyImport_Import失败
- 将 C# DLL 导入 C++ 以用于 JNI
- 使用 QSslCertificate 在 Qt 中正确导入 pkcs12
- 在从Qt调用的Python脚本中导入OpenCV崩溃
- 编译boost_python扩展无法在 python 2.7 中导入
- 如何在安卓工作室中将c ++头文件从一个文件夹导入到另一个文件夹?
- Dll在同一解决方案中从 c# 项目导入到 c++ 项目
- C++20 使用 Visual Studio 编译模块:不编译或导入 ixx 文件
- 如何"disable"从 C 标头导入的宏