Вопрос-Ответ

Calling C/C++ from Python? [closed]

Вызов C / C ++ из Python?

Каким был бы самый быстрый способ создать привязку Python к библиотеке C или C ++?

(Я использую Windows, если это имеет значение.)

Переведено автоматически
Ответ 1

модульctypes является частью стандартной библиотеки и, следовательно, более стабилен и широко доступен, чем swig, который всегда вызывал у меня проблемы.

С помощью ctypes вам нужно удовлетворять любой зависимости от python во время компиляции, и ваша привязка будет работать с любым python, у которого есть ctypes , а не только с тем, для которого она была скомпилирована.

Предположим, у вас есть простой пример класса C ++, с которым вы хотите взаимодействовать в файле с именем foo.cpp:

#include <iostream>

class Foo{
public:
void bar(){
std::cout << "Hello" << std::endl;
}
};

Поскольку ctypes могут взаимодействовать только с функциями C, вам необходимо предоставить те, которые объявляют их как extern "C"

extern "C" {
Foo* Foo_new(){ return new Foo(); }
void Foo_bar(Foo* foo){ foo->bar(); }
}

Затем вам нужно скомпилировать это в общую библиотеку

g++ -c -fPIC foo.cpp -o foo.o
g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o

И, наконец, вам нужно написать свою оболочку python (например, в fooWrapper.py)

from ctypes import cdll
lib = cdll.LoadLibrary('./libfoo.so')

class Foo(object):
def __init__(self):
self.obj = lib.Foo_new()

def bar(self):
lib.Foo_bar(self.obj)

Как только у вас это получится, вы можете вызвать это следующим образом

f = Foo()
f.bar() #and you will see "Hello" on the screen
Ответ 2

Вам стоит взглянуть на Boost.Python. Вот краткое введение, взятое с их веб-сайта:


The Boost Python Library is a framework for interfacing Python and
C++. It allows you to quickly and seamlessly expose C++ classes
functions and objects to Python, and vice-versa, using no special
tools -- just your C++ compiler. It is designed to wrap C++ interfaces
non-intrusively, so that you should not have to change the C++ code at
all in order to wrap it, making Boost.Python ideal for exposing
3rd-party libraries to Python. The library's use of advanced
metaprogramming techniques simplifies its syntax for users, so that
wrapping code takes on the look of a kind of declarative interface
definition language (IDL).


Ответ 3

There is also pybind11, which is like a lightweight version of Boost.Python and compatible with all modern C++ compilers:

https://pybind11.readthedocs.io/en/latest/

Ответ 4

The quickest way to do this is using SWIG.

Example from SWIG tutorial:

/* File : example.c */
int fact(int n) {
if (n <= 1) return 1;
else return n*fact(n-1);
}

Interface file:

/* example.i */
%module example
%{
/* Put header files here or function declarations like below */
extern int fact(int n);
%}

extern int fact(int n);

Building a Python module on Unix:

swig -python example.i
gcc -fPIC -c example.c example_wrap.c -I/usr/local/include/python2.7
gcc -shared example.o example_wrap.o -o _example.so

Usage:

>>> import example
>>> example.fact(5)
120

Note that you have to have python-dev. Also in some systems python header files will be in /usr/include/python2.7 based on the way you have installed it.

From the tutorial:


SWIG is a fairly complete C++ compiler with support for nearly every language feature. This includes preprocessing, pointers, classes, inheritance, and even C++ templates. SWIG can also be used to package structures and classes into proxy classes in the target language — exposing the underlying functionality in a very natural manner.


2023-06-20 00:07 python