Создание типа Python в C с использованием внешней библиотеки: ctypes или setuptools?

Я пишу какое-то расширение Python C. Он использует мою собственную библиотеку *.so и заголовки из другого проекта (допустим, они находятся в /usr/local/lib/otherproject.so и /usr/local/include/otherproject.h).

Я не знаю, какой стратегии придерживаться. Я придумал два:

Как чистое расширение Python

Напишите расширение Python C, как описано в официальной документации. Проблема здесь в том, что я не знаю, как связать свою собственную библиотеку и заголовки; для компиляции я пишу файл setup.py и запускаю python3.4 setup.py build. Я не знаю, могу ли я включить какую-либо опцию в предыдущую команду или могу ли я написать что-то в setup.py, чтобы включить мои заголовки и двоичные файлы (если да, мне также придется беспокоиться о том, чтобы сделать этот дистрибутив?).

С ctypes

Напишите библиотеку C (с системой сборки моего другого проекта). Включите Python, передав '/usr/include/python2.7' для поиска заголовков и двоичного файла python2.7. Затем используйте ctypes, чтобы обернуть эту библиотеку и получить функции, типы, объекты и т. д. Неудобство здесь в том, что мне нужно вручную обернуть каждую отдельную функцию/тип/переменную из ctypes; Я не думаю, что смогу использовать PyModule_AddObject, так как я создаю модуль не на C, а в оболочке Python (с ctypes).


Кроме того, я попробовал второй подход, но не смог успешно получить свой пользовательский объект PyTypeObject из ctypes. Если второй подход звучит хорошо для любого более опытного мозга здесь, на SO, я бы разместил код, чтобы получить любую помощь =).


person jleeothon    schedule 08.12.2015    source источник


Ответы (1)


Второй подход также приводит к проблемам с распределением. И если вы создаете объект Python в C, вы должны делать это в контексте модуля. Для сценариев, где распространение проблематично, вместо этого вы можете связать этот модуль статически.

По вашей проблеме со связыванием вы найдете дополнительную информацию об параметрах библиотеки в документации. Поскольку ваша библиотека находится в каталоге, который должен находиться в стандартном пути поиска библиотеки, вам нужно только определить свою библиотеку с опцией libraries класса Extension:

mymodule_ext = Extension('mymodule', ['mymodule.c'], libraries=['otherproject'])

Если вы не используете стандартный префикс lib*, вам нужно использовать вместо него libraries=[':otherproject.so'].

person tynn    schedule 19.12.2015
comment
Спасибо! Я следовал первому описанному выше подходу и да, обнаружил libraries, library_dirs и include_dirs, которые помогают мне создавать расширения Python и связываться с другими моими вещами. - person jleeothon; 23.12.2015