С - расширения

Источники

Зачем использовать вставки другого кода

  • С работает быстрее;
  • нужна конкретная библиотека на С и не хочется переписывать ее на питон;
  • нужен низкоуровневый интерфейс управления ресурсами для работы с памятью и файлами.

Что использовать для вызова С-функции

Один из механизмов:

  • ctypes
  • SWIG
  • Python/C API

Как сделать файл-библиотеку на языке С или С++

SWIG FAQ

С-код, который мы будем дальше использовать

/* sample.c */
#include <math.h>
/* Compute the greatest common divisor */
int gcd(int x, int y) {
    int g = y;
    while (x > 0) {
        g = x;
        x = y % x;
        y = g;
    }
    return g;
}
/* Test if (x0,y0) is in the Mandelbrot set or not */
int in_mandel(double x0, double y0, int n) {
    double x=0,y=0,xtemp;
    while (n > 0) {
        xtemp = x*x - y*y + x0;
        y = 2*x*y + y0;
        x = xtemp;
        n -= 1;
        if (x*x + y*y > 4) return 0;
    }
    return 1;
}
/* Divide two numbers */
int divide(int a, int b, int *remainder) {
    int quot = a / b;
    *remainder = a % b;
    return quot;
}
/* Average values in an array */
double avg(double *a, int n) {
    int i;
    double total = 0.0;
    for (i = 0; i < n; i++) {
        total += a[i];
    }
    return total / n;
}
/*A C data structure */
typedef struct Point {
    double x,y;
} Point;
/* Function involving a C data structure */
double distance(Point *p1, Point *p2) {
    return hypot(p1->x - p2->x, p1->y - p2->y);
}
  • gdc и is_mandel - простые функции от int и double, которые возвращают значения;
  • divide - возвращает, по сути, 2 числа - частное и записывает остаток от деления по указанному адресу;
  • avg - перебирает массив, переданный как указатель;
  • Point и distance - работают со структурами.

Пусть прототипы функций файла sample.c заданы в sample.h и сам файл собран в библиотеку libsample.so.

Диагностика segmentation faults

Что-то пошло не так и программа упала. Хочется получить информативный trace падения. Воспользуемся модулем faulthandler

Из кода питона:

import faulthandler
faulthandler.enable()

или запустим питон с опцией -Xfaulthandler:

bash % python3 -Xfaulthandler program.py

или определите переменную окружения PYTHONFAULTHANDLER.

Если ваша программа с использованием С-кода упала, вы получите сообщение вида:

Fatal Python error: Segmentation fault
Current thread 0x00007fff71106cc0:
File "example.py", line 6 in foo
File "example.py", line 10 in bar
File "example.py", line 14 in spam
File "example.py", line 19 in <module>
Segmentation fault

Далее воспользуйтесь питон дебагером pdb и С-дебагером (например, gdb) для исследования С-части.

It should be noted that certain kinds of errors in C may not be easily recoverable. For example, if a C extension trashes the stack or program heap, it may render faulthan dler inoperable and you’ll simply get no output at all (other than a crash). Obviously, your mileage may vary.

results matching ""

    No results matching ""