6

Вызов C/C++ из Python? [закрыто]

12

Проблема: Поиск метода для создания Python-обертки для библиотеки C/C++

Здравствуйте!

Я пытаюсь создать обертку для библиотеки на C или C++, чтобы использовать её в своем проекте на Python. Мне нужно быстрое решение, и я работаю в среде Windows.

Какой самый простой и быстрый способ создать привязку Python к библиотеке на C/C++? Можно ли использовать какие-либо доступные инструменты или библиотеки для упрощения этого процесса?

Буду благодарен за любые советы и рекомендации!

4 ответ(ов)

0

Для современного 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.

0

Я думаю, что cffi для Python может быть хорошим вариантом.

Цель состоит в том, чтобы вызывать код на C из Python. Вам не придется учить третий язык: каждая альтернативная библиотека требует изучения собственного языка (Cython, SWIG) или API (ctypes). Мы постарались сделать так, чтобы вы знали Python и C и свели к минимуму дополнительную часть API, которую вам нужно изучить.

Более подробную информацию можно найти в документации cffi.

0

Я тоже очень люблю 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++ кода каждый раз.

0

Cython определённо стоит использовать, если вы не планируете писать Java-обёртки, в этом случае SWIG может быть более предпочтительным выбором.

Я рекомендую использовать утилиту командной строки runcython, она делает процесс работы с Cython очень простым. Если вам нужно передавать структурированные данные в C++, обратите внимание на библиотеку protobuf от Google, она очень удобна.

Вот минимальный пример, который я создал, использующий оба инструмента:

https://github.com/nicodjimenez/python2cpp

Надеюсь, это будет полезной отправной точкой.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь