Доступ к магическим числам / флагам заголовка C с помощью Cython - PullRequest
4 голосов
/ 05 февраля 2010

Некоторые стандартные библиотеки C, к которым я хочу получить доступ с помощью Cython, имеют массу флагов. Документы Cython заявляют, что я должен воспроизвести те части заголовка, которые мне нужны. Что хорошо, когда дело доходит до определений функций. Они обычно тиражируются повсюду, включая документы. Но как насчет всех этих магических чисел?

Если я хочу вызвать mmap, я всегда могу найти определение функции и вставить его в файл .pxd:

void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)

Но для его вызова нужна тонна флагов, таких как PROT_READ, MAP_ANONYMOUS и так далее. У меня есть как минимум две проблемы с этим:

Во-первых, надоедливо выслеживать, где именно эти числа определены. На самом деле я предпочел бы написать файл .c и распечатать нужные мне значения. Есть ли лучший способ найти значение данного флага, например PROT_READ?

Во-вторых, насколько стабильны эти числа? Извлекая все нужные мне значения и жестко запрограммировав их в исходный код Cython, каковы шансы того, что компиляция на другой платформе переключилась, скажем, PROT_READ и PROT_EXEC?

Даже если ответ таков, что нет хороших или правильных способов сделать это, я бы хотел услышать это. Я всегда могу смириться с тем, что что-то громоздко, если я знаю, что что-то не упустил.

Ответы [ 3 ]

6 голосов
/ 06 февраля 2010

Чтобы использовать эти константы из Cython, вам не нужно точно определять, откуда они пришли или чем они отличаются от вас, например, из C. Например, ваш файл .pxd может выглядеть как

cdef extern from "foo.h":
    void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
    cdef int PROT_READ
    cdef int MAP_ANONYMOUS
    ...

Пока определения (прямо или косвенно) включены из foo.h, это должно работать нормально.

2 голосов
/ 05 февраля 2010

Есть несколько возможных альтернатив:

  1. Используйте флаги из модуля Python mmap.
    • простой
    • работает только при наличии существующих привязок Python
  2. Сначала используйте объект Python mmap и передайте его в свой код Cython
    • еще более простое открытие
    • может иметь некоторые накладные расходы Python
  3. Используйте генератор кода ctypeslib
  4. Просто скопируйте числа.

При этом цифры очень и очень стабильны. Если бы они изменились, то каждая C-программа, использующая mmap, должна была бы перекомпилироваться, так как флаги из заголовков содержатся в двоичном файле.

РЕДАКТИРОВАТЬ : mmap является частью POSIX , но поверхностное чтение не выявило, должны ли флаги быть одинаковыми на всех платформах.

1 голос
/ 05 февраля 2010

Напишите файл foo.c с таким содержимым:

#include <sys/mman.h>

Затем запустите

cpp -dM foo.c | grep -v __ | awk '{if ($3) print $2, "=", $3}' > mman.py

, который создаст файл python, который определяет все константы из mman.h

Очевидно, что вы можете сделать это для нескольких включений, если хотите.

Получившийся файл, возможно, потребуется немного очистить, но он приблизит вас.

...