Использование Cython Для Связи Python С Общей Библиотекой
Я пытаюсь интегрировать стороннюю библиотеку, написанную в C
мой python
применение с помощью Cython
. У меня есть весь код python, написанный для теста. У меня возникли проблемы с поиском пример настройки.
у меня есть pyd/pyx
файл, который я создал вручную. Третья сторона дала мне header file (*.h)
и shared library (*.so)
. Насколько я могу судить, других зависимостей нет. Может ли кто-нибудь привести пример того, как настроить это с помощью Cython
и disutils
?
спасибо
1 ответов
точно !
(в следующем, Я предполагаю, что вы уже знаете, как бороться с cimport
и взаимодействий между .pxd
и .pyx
. Если это не совсем так, просто спросите, и я разработаю эту часть)
образец (взятый из моего проекта C++, но проект C будет работать почти так же):
1. Файл установки Distutils:
предполагая, что расширение будет создано будет называться myext
и сторонняя общая библиотека libexternlib.so
(обратите внимание на lib* префикс, здесь)...
# setup.py file
import sys
import os
import shutil
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
# clean previous build
for root, dirs, files in os.walk(".", topdown=False):
for name in files:
if (name.startswith("myext") and not(name.endswith(".pyx") or name.endswith(".pxd"))):
os.remove(os.path.join(root, name))
for name in dirs:
if (name == "build"):
shutil.rmtree(name)
# build "myext.so" python extension to be added to "PYTHONPATH" afterwards...
setup(
cmdclass = {'build_ext': build_ext},
ext_modules = [
Extension("myext",
sources=["myext.pyx",
"SomeAdditionalCppClass1.cpp",
"SomeAdditionalCppClass2.cpp"
],
libraries=["externlib"], # refers to "libexternlib.so"
language="c++", # remove this if C and not C++
extra_compile_args=["-fopenmp", "-O3"],
extra_link_args=["-DSOME_DEFINE_OPT",
"-L./some/extra/dependency/dir/"]
)
]
)
Примечание : внешний .so
файл связан через :
libraries=["externlib"] # Without the 'lib' prefix and the '.so' extension...
Примечание:sources
опция может использоваться, чтобы получить некоторые дополнительные исходные файлы скомпилированы.
важно : myext.pxd
(не путайте с .pyd
- Windows stuff) и myext.pyx
должен быть в тот же каталог. Во время компиляции файл определения, если он существует, обрабатывается первым (больше).
2. Запустите его следующим образом :
после изменения каталога на тот, который содержит ваш myext.pxd
ваш myext.pyx
, а также выше setup.py
сценарий :
# setup.sh
# Make the "myext" Python Module ("myext.so")
CC="gcc" \
CXX="g++" \
CFLAGS="-I./some/path/to/includes/ -I../../../DEPENDENCIES/python2.7/inc -I../../../DEPENDENCIES/gsl-1.15" \
LDFLAGS="-L./some/path/to/externlib/" \
python setup.py build_ext --inplace
где :
-
libexternlib.so
предполагается, что находится по адресу./some/path/to/externlib/
-
yourheader.h
предполагается, что находится по адресу./some/path/to/includes/
Примечание : CFLAGS
также можно было настроить с помощью :
extra_compile_args=["-I./some/path/to/includes/", "-fopenmp", "-O3"]
Примечание : LDFLAGS
также можно было настроить с помощью :
extra_link_args=["-L./some/path/to/externlib/", "-DSOME_DEFINE_OPT", "-L./some/extra/dependency/dir/"]
как только distutils будет сделано со сборкой, вы получите несколько новых файлов, особенно myext.cpp
, myext.h
и самое главное myext.so
.
3. После этого ты можешь идти. :
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./some/path/to/externlib/
export PYTHONPATH=$PYTHONPATH:./some/path/to/myext/
# Run some script requiring "myext.so"
python somescript.py
где ваше недавно созданное расширение Python может быть импортировано по его имени:
# somescript.py
import myext
from myext import PySomeFeature
...
Примечание об оптимизации : по умолчанию -O2
используется для компиляции расширения, но это может быть перегружено (см. выше настройка, где -O3
указан).
Примечание о путях Cython: если Cython был установлен в пользовательском каталоге, вы можете добавить его в свою среду, прежде чем все :
PYTHONPATH=$PYTHONPATH:../../../DEPENDENCIES/Cython-0.18 export PYTHONPATH;
PATH=$PATH:../../../DEPENDENCIES/Cython-0.18/bin; export PATH;
ну, надеюсь, я осветил основные моменты...