math_sin
определяется с помощью макроса FUNC1
:
FUNC1(sin, sin, 0,
"sin($module, x, /)\n--\n\n"
"Return the sine of x (measured in radians).")
, где FUNC1
определяется как :
#define FUNC1(funcname, func, can_overflow, docstring) \
static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
return math_1(args, func, can_overflow); \
}\
PyDoc_STRVAR(math_##funcname##_doc, docstring);
поэтому препроцессор расширяет это до:
static PyObject * math_sin(PyObject *self, PyObject *args) {
return math_1(args, sin, 0);
}
PyDoc_STRVAR(math_sin_doc, "sin($module, x, /)\n--\n\n"
"Return the sine of x (measured in radians).");
(но затем все в одной строке и с расширением макроса PyDoc_STRVAR
)
Таким образом, math_sin(module, args)
в основном является вызовом math_1(args, sin, 0)
, а math_1(args, sin, 0)
вызывает math_1_to_whatever(args, sin, PyFloat_FromDouble, 0)
, который заботится о проверке, что было передано число с плавающей точкой Python, преобразовывая в C double, вызывая sin(arg_as_double)
, вызывая при необходимости исключения или оборачивая двойное возвращаемое значение из sin()
с помощью функции PyFloat_FromDouble
, переданной math_1()
, перед возвратом этого результата вызывающей стороне.
sin()
здесь double sin(double x)
функция, определенная в POSIX math.h
.
В принципе, вы можете предварительно обработать все исходное дерево Python и вывести вывод в новый каталог; следующее предполагает, что вы успешно создали двоичный файл python
, так как он используется для извлечения необходимых флагов включения для gcc
:
find . -type d -exec mkdir -p /tmp/processed/{} \;
(export FLAGS=$(./python.exe -m sysconfig | grep PY_CORE_CFLAGS | cut -d\" -f2) && \
find . -type f \( -name '*.c' -o -name '*.h' \) -exec gcc -E $FLAGS {} -o /tmp/processed/{} \;)
, а затем math_sin
появится в /tmp/preprocessed/Modules/mathmodule.c
.
Или вы можете указать компилятору сохранять выходные данные препроцессора в .i
файлах с флагом -save-temps
:
make clean && make CC="gcc -save-temps"
и вы найдете make_sin
в Modules/mathmodule.i
.