Detaillierte Erklärung, wie Python C++-Programme aufruft

高洛峰
Freigeben: 2017-02-20 10:28:28
Original
1451 Leute haben es durchsucht

Vorwort

Jeder weiß, dass die Vorteile von Python eine hohe Entwicklungseffizienz und Benutzerfreundlichkeit sind, während C++ eine hohe Betriebseffizienz aufweist. Die beiden können sich gegenseitig ergänzen in Python Wenn Sie C++-Code in ein Projekt einbetten oder Python zum Implementieren von Peripheriefunktionen in einem C++-Projekt verwenden, müssen Sie möglicherweise C++-Module aufrufen. Hier sind einige grundlegende Methoden zum Exportieren von C++-Code in Python-Schnittstellen zusammen. .

Originalexport

Der Python-Interpreter ist in C implementiert, sofern unsere C++-Datenstruktur von Python verstanden werden kann Theoretisch kann es direkt aufgerufen werden. Wir implementieren test1.cpp wie folgt

#include <Python.h>

int Add(int x, int y)
{
 return x + y;
}

int Del(int x, int y)
{
 return x - y;
}

PyObject* WrappAdd(PyObject* self, PyObject* args)
{
 int x, y;
 if (!PyArg_ParseTuple(args, "ii", &x, &y))
 {
  return NULL;
 }
 return Py_BuildValue("i", Add(x, y));
}

PyObject* WrappDel(PyObject* self, PyObject* args)
{
 int x, y;
 if (!PyArg_ParseTuple(args, "ii", &x, &y))
 {
  return NULL;
 }
 return Py_BuildValue("i", Del(x, y));
}
static PyMethodDef test_methods[] = {
 {"Add", WrappAdd, METH_VARARGS, "something"},
 {"Del", WrappDel, METH_VARARGS, "something"},
 {NULL, NULL}
};

extern "C"
void inittest1()
{
 Py_InitModule("test1", test_methods);
}
Nach dem Login kopieren

Der Kompilierungsbefehl lautet wie folgt

g++ -fPIC -shared test1.cpp -I/usr/include/python2.6 -o test1.so
Nach dem Login kopieren

Führen Sie den Python-Interpreter aus und testen Sie ihn wie folgt

>>> import test1
>>> test1.Add(1,2)
3
Nach dem Login kopieren

Hier sind einige Punkte zu beachten

  1. Wenn der Name der generierten dynamischen Bibliothek test1 ist, muss die Quelldatei die Funktion inittest1 haben und der erste Parameter von Py_InitModule muss „test1“ sein, andernfalls Python Das Importieren des Moduls schlägt fehl

  2. Wenn es sich um eine CPP-Quelldatei handelt, muss die Funktion inittest1 mit extern „C“ geändert werden. Wenn es sich um eine C-Quelldatei handelt, ist sie nicht erforderlich. Der Grund dafür ist, dass der Python-Interpreter beim Importieren von Bibliotheken nach Funktionen wie initxxx sucht und C++ Funktionssymbole unterschiedlich codiert. C++ berücksichtigt beim Codieren von Funktionssymbolen insbesondere die Funktion nm test1.so Die Funktionssymbole. Das C++-Filtertool kann den Funktionsprototyp durch die durch Boost implementierten Symbole

invertieren > Wir verwenden das gleiche Beispiel wie oben, um test2.cpp wie folgt zu implementieren

#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace boost::python;

int Add(const int x, const int y)
{
 return x + y;
}

int Del(const int x, const int y)
{
 return x - y;
}

BOOST_PYTHON_MODULE(test2)
{
 def("Add", Add);
 def("Del", Del);
}
Nach dem Login kopieren
Der Parameter von BOOST_PYTHON_MODULE ist der Name von das zu exportierende Modul

Der Kompilierungsbefehl lautet wie folgt

g++ test2.cpp -fPIC -shared -o test2.so -I/usr/include/python2.6 -I/usr/local/include -L/usr/local/lib -lboost_python
Nach dem Login kopieren

Hinweis:

muss beim Kompilieren den Boost-Header angeben. Die Pfade von Dateien und Bibliotheken sind hier /usr/local/include und /usr/local/lib oder exportieren Sie das Modul über setup.py

#!/usr/bin/env python
from distutils.core import setup
from distutils.extension import Extension

setup(name="PackageName",
 ext_modules=[
  Extension("test2", ["test2.cpp"],
  libraries = ["boost_python"])
 ])
Nach dem Login kopieren
Der erste Parameter von Extension ist der Modulname und der zweite Parameter ist der Dateiname

Führen Sie den folgenden Befehl aus

python setup.py build
Nach dem Login kopieren
Das Build-Verzeichnis wird zu diesem Zeitpunkt generiert. Suchen Sie darin test2.so, geben Sie das Verzeichnis derselben Ebene ein und überprüfen Sie es wie folgt

>>> import test2
>>> test2.Add(1,2)
3
>>> test2.Del(1,2)
-1
Nach dem Login kopieren
Klasse exportieren

test3.cpp wird wie folgt implementiert

#include <boost/python.hpp>
using namespace boost::python;

class Test
{
public:
 int Add(const int x, const int y)
 {
  return x + y;
 }

 int Del(const int x, const int y)
 {
  return x - y;
 }
};

BOOST_PYTHON_MODULE(test3)
{
 class_<Test>("Test")
  .def("Add", &Test::Add)
  .def("Del", &Test::Del);
}
Nach dem Login kopieren

Hinweis:

BOOST_PYTHON_MODULE Die Verwendung von .def ähnelt in gewisser Weise der Python-Syntax, die äquivalent zu

< ist 🎜>

Der Kompilierungsbefehl lautet wie folgt
class_<Test>("Test").def("Add", &Test::Add);
class_<Test>("Test").def("Del", &Test::Del);
Nach dem Login kopieren

Der Test lautet wie folgt
g++ test3.cpp -fPIC -shared -o test3.so -I/usr/include/python2.6 -I/usr/local/include/boost -L/usr/local/lib -lboost_python
Nach dem Login kopieren

>>> import test3
>>> test = test3.Test()
>>> test.Add(1,2)
3
>>> test.Del(1,2)
-1
Nach dem Login kopieren

Variable Parameterfunktion exportieren

test4.cpp wird wie folgt implementiert

Hier verwenden die Funktionen „Add“ und „Del“ beide Standardparameter, „Del“ ist eine gewöhnliche Funktion und „Add“ ist eine Klassenmitgliedsfunktion. Hier werden unterschiedliche Makros aufgerufen. Die letzten beiden Parameter des Makros stellen die dar minimale Anzahl von Parametern bzw. maximale Anzahl von Parametern der Funktion
#include <boost/python.hpp>
using namespace boost::python;

class Test
{
public:
 int Add(const int x, const int y, const int z = 100)
 {
  return x + y + z;
 }
};

int Del(const int x, const int y, const int z = 100)
{
 return x - y - z;
}

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Add_member_overloads, Add, 2, 3)
BOOST_PYTHON_FUNCTION_OVERLOADS(Del_overloads, Del, 2, 3)

BOOST_PYTHON_MODULE(test4)
{
 class_<Test>("Test")
  .def("Add", &Test::Add, Add_member_overloads(args("x", "y", "z"), "something"));
 def("Del", Del, Del_overloads(args("x", "y", "z"), "something"));
}
Nach dem Login kopieren

Der Kompilierungsbefehl lautet wie folgt

Der Test ist wie folgt
g++ test4.cpp -fPIC -shared -o test4.so -I/usr/include/python2.6 -I/usr/local/include/boost -L/usr/local/lib -lboost_python
Nach dem Login kopieren

>>> import test4
>>> test = test4.Test()
>>> print test.Add(1,2)
103
>>> print test.Add(1,2,z=3)
6
>>> print test4.Del(1,2)
-1
>>> print test4.Del(1,2,z=3)
-1
Nach dem Login kopieren

Exportschnittstelle mit Python-Objekten

Seitdem Wenn es als Python-Schnittstelle exportiert wird, verwendet der Aufrufer zwangsläufig Python-spezifische Datenstrukturen wie Tupel, Liste und Diktat. Da die ursprüngliche ökologische Methode zu mühsam ist, wird hier nur die Verwendung von Boost aufgezeichnet Ich möchte die folgende Python-Funktion

implementieren, d. h. das Quadrat jedes Elements der übergebenen Liste berechnen und das Ergebnis vom Listentyp zurückgeben
def Square(list_a)
{
 return [x * x for x in list_a]
}
Nach dem Login kopieren

Der Code lautet wie folgt

Der Kompilierungsbefehl lautet wie folgt
#include <boost/python.hpp>

boost::python::list Square(boost::python::list& data)
{
 boost::python::list ret;
 for (int i = 0; i < len(data); ++i)
 {
  ret.append(data[i] * data[i]);
 }

 return ret;
}

BOOST_PYTHON_MODULE(test5)
{
 def("Square", Square);
}
Nach dem Login kopieren

Der Test ist wie folgt
g++ test5.cpp -fPIC -shared -o test5.so -I/usr/include/python2.6 -I/usr/local/include/boost -L/usr/local/lib -lboost_python
Nach dem Login kopieren

Boost implementiert die Datentypen
>>> import test5
>>> test5.Square([1,2,3])
[1, 4, 9]
Nach dem Login kopieren
,

,

, und die Verwendungsmethode stimmt im Wesentlichen mit Python überein. Für bestimmte Methoden können Sie boost/python/tuple.hpp und andere entsprechende Dateien in der Boost-Header-Datei anzeigen

boost::python::tuple Eine weitere häufig verwendete Funktion ist boost::python::list, und die Verwendungsmethode ist wie folgt boost::python::dict

boost::python::make_tuple()

Ausführlichere Erklärungen, wie Python C++-Programme aufruft, und verwandte Artikel finden Sie auf der chinesischen PHP-Website !
boost::python::tuple(int a, int b, int c)
{
 return boost::python::make_tuple(a, b, c);
}
Nach dem Login kopieren
Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!