I make this third party package to solve the mainly macro pollute from “<pyconfig.h>” in python:
Initialization
You can install it and use the command to initialize the module:
pip install python_undef
python -m python_undef --generate
Usage
Ensure available
Before write the c code, you need to check whether “Python_keep.h” and “Python_undef.h” available:
python -m python_undef --include
It will output the header file path if it is available.
Include it
You need to keep the order below:
#include <Python_keep.h>
#include <Python.h>
#include <Python_undef.h>
Effect
The “pyconfig.h” contains different content on different systems and devices. You can test it steadly on windows because the “pyconfig.h” on windows is frozen.
For example, under 3.14, “pyconfig.h” on windows will define the macro “COMPILER”, if you also use this name there will be a comflict.
This is the expect result on windows(the command then are
gcc "-I$(python -c `"import sysconfig;print(sysconfig.get_path('include'))`")" "-I$(python -m python_undef --include)" test.cpp -o test.exe
):
// test.cpp
#define COMPILER 1
#include <stdio.h>
int main() {
#if COMPILER==1
printf("Hello world!");
#else
int a = COMPILER;
printf("The result of a is %d\n", a);
#endif
return 0;
}
You define the macro “COMPILER” value 1, so finally it will compile “printf(“Hello world!”);”. Running “test.exe” will print “Hello world!”.
If we change the value to 2, finally it will print “The result of a is 2”.
Then we add “#include <Python.h>”:
// test.cpp
#define COMPILER 1
#include <Python.h>
#include <stdio.h>
int main() {
#if COMPILER==1
printf("Hello world!");
#else
int a = COMPILER;
printf("The result of a is %d\n", a);
#endif
return 0;
}
On windows, it will redefine the macro “COMILER” to the value "[GCC]" (It is a string). "[GCC]" == 1 cannot work, so the compiling will fail.
Finally, we add “Python_keep.h” and “Python_undef.h”:
// test.cpp
#define COMPILER 1
#include <Python_keep.h>
#include <Python.h>
#include <Python_undef.h>
#include <stdio.h>
int main() {
#if COMPILER==1
printf("Hello world!");
#else
int a = COMPILER;
printf("The result of a is %d\n", a);
#endif
return 0;
}
The macro “COMPILER” will be recoveried to 1, so the behavior is same to the beginning.
On unix, you can open the “pyconfig.h” and read it to decide which macro to use to test it.