Вызов C/C++ из Python? [закрыто]
Проблема: Поиск метода для создания Python-обертки для библиотеки C/C++
Здравствуйте!
Я пытаюсь создать обертку для библиотеки на C или C++, чтобы использовать её в своем проекте на Python. Мне нужно быстрое решение, и я работаю в среде Windows.
Какой самый простой и быстрый способ создать привязку Python к библиотеке на C/C++? Можно ли использовать какие-либо доступные инструменты или библиотеки для упрощения этого процесса?
Буду благодарен за любые советы и рекомендации!
4 ответ(ов)
Для современного C++, используйте cppyy:
http://cppyy.readthedocs.io/en/latest/
Он основан на Cling, интерпретаторе C++ для Clang/LLVM. Связывание происходит во время выполнения, и дополнительный промежуточный язык не требуется. Благодаря Clang он поддерживает C++17.
Установите его через pip:
$ pip install cppyy
Для небольших проектов просто загрузите соответствующую библиотеку и заголовки, которые вас интересуют. Например, используйте код из примера с ctypes в этой теме, но разделите его на части с заголовками и кодом:
$ cat foo.h
class Foo {
public:
void bar();
};
$ cat foo.cpp
#include "foo.h"
#include <iostream>
void Foo::bar() { std::cout << "Hello" << std::endl; }
Скомпилируйте его:
$ g++ -c -fPIC foo.cpp -o foo.o
$ g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o
И используйте его:
$ python
>>> import cppyy
>>> cppyy.include("foo.h")
>>> cppyy.load_library("foo")
>>> from cppyy.gbl import Foo
>>> f = Foo()
>>> f.bar()
Hello
>>>
Большие проекты поддерживаются с автозагрузкой подготовленной информации о рефлексии и фрагментов cmake для их создания, так что пользователи установленных пакетов могут просто запустить:
$ python
>>> import cppyy
>>> f = cppyy.gbl.Foo()
>>> f.bar()
Hello
>>>
Благодаря LLVM возможны продвинутые функции, такие как автоматическая инстанциация шаблонов. Продолжая пример:
>>> v = cppyy.gbl.std.vector[cppyy.gbl.Foo]()
>>> v.push_back(f)
>>> len(v)
1
>>> v[0].bar()
Hello
>>>
Примечание: Я автор cppyy.
Я думаю, что cffi для Python может быть хорошим вариантом.
Цель состоит в том, чтобы вызывать код на C из Python. Вам не придется учить третий язык: каждая альтернативная библиотека требует изучения собственного языка (Cython, SWIG) или API (ctypes). Мы постарались сделать так, чтобы вы знали Python и C и свели к минимуму дополнительную часть API, которую вам нужно изучить.
Более подробную информацию можно найти в документации cffi.
Я тоже очень люблю cppyy — он делает расширение Python C++ кодом невероятно простым и значительно увеличивает производительность, когда это необходимо.
Это мощный инструмент и, честно говоря, очень прост в использовании.
Вот пример того, как можно создать массив numpy и передать его в функцию-член класса на C++.
cppyy_test.py
import cppyy
import numpy as np
cppyy.include('Buffer.h')
s = cppyy.gbl.Buffer()
numpy_array = np.empty(32000, np.float64)
s.get_numpy_array(numpy_array.data, numpy_array.size)
print(numpy_array[:20])
Buffer.h
struct Buffer {
void get_numpy_array(double *ad, int size) {
for( long i=0; i < size; i++)
ad[i] = i;
}
};
Вы также можете очень просто создать Python модуль (с помощью CMake), и таким образом избежать необходимости перекомпиляции C++ кода каждый раз.
Cython определённо стоит использовать, если вы не планируете писать Java-обёртки, в этом случае SWIG может быть более предпочтительным выбором.
Я рекомендую использовать утилиту командной строки runcython
, она делает процесс работы с Cython очень простым. Если вам нужно передавать структурированные данные в C++, обратите внимание на библиотеку protobuf от Google, она очень удобна.
Вот минимальный пример, который я создал, использующий оба инструмента:
https://github.com/nicodjimenez/python2cpp
Надеюсь, это будет полезной отправной точкой.
Как изменить цвет вывода echo в Linux
В чем разница между #include <filename> и #include "filename"?
Как использовать extern для обмена переменными между исходными файлами?
Что должно возвращать main() в C и C++?
Разница между использованием Makefile и CMake для компиляции кода?