Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ebben a cikkben egy C++ bővítménymodult hoz létre a CPythonhoz egy hiperbolikus tangens kiszámításához és Python-kódból való meghívásához. A rutint először Pythonban valósítjuk meg, hogy bemutassuk a C++-ban történő megvalósításának relatív teljesítménynövekedését.
A C++ (vagy C) nyelven írt kódmodulokat gyakran használják a Python-értelmező képességeinek bővítésére. A bővítménymodulok három elsődleges típusa létezik:
- Gyorsítómodulok: Gyorsított teljesítmény engedélyezése. Mivel a Python értelmezett nyelv, a nagyobb teljesítmény érdekében a C++-ban is írhat egy gyorsítómodult.
- Burkolómodulok: Meglévő C/C++ interfészek közzététele Python-kód számára, vagy egy Python-szerű API közzététele, amely könnyen használható a Pythonból.
-
Alacsony szintű rendszerelérési modulok: Rendszerelérési modulok létrehozása a
CPythonfuttatókörnyezet, az operációs rendszer vagy a mögöttes hardver alacsonyabb szintű funkcióinak eléréséhez.
Ez a cikk két módon teszi elérhetővé a C++ bővítménymodult a Python számára:
- Használja a
CPythonleírt standard bővítményeket. - Használja a PyBind11-et, amelyet egyszerűsége miatt a C++11-hez ajánlunk. A kompatibilitás biztosítása érdekében győződjön meg arról, hogy a Python egyik legújabb verziójával dolgozik.
Az útmutató befejezett mintája a GitHubon érhető el a Python-samples-vs-cpp-extension címen.
Előfeltételek
Visual Studio 2017 vagy újabb verzió, telepített Python-fejlesztési számítási feladattal. A számítási feladat tartalmazza a Python natív fejlesztési eszközeit, amelyek hozzáadják a C++ számítási feladatot, és natív bővítményekhez szükséges eszközöket építenek ki.
A telepítési lehetőségekről további információt a Visual Studio Python-támogatásának telepítése című témakörben talál.
Megjegyzés:
Az adatelemzési és elemzési alkalmazások számítási feladatainak telepítésekor a Python és a Python natív fejlesztői eszközei alapértelmezés szerint telepítve lesznek.
Ha külön telepíti a Pythont, mindenképpen válassza a Hibakeresési szimbólumok letöltése lehetőséget a Python-telepítő Speciális beállítások területén . Ez a beállítás szükséges ahhoz, hogy vegyes módú hibakeresést használjon a Python-kód és a natív kód között.
A Python-alkalmazás létrehozása
Kövesse az alábbi lépéseket a Python-alkalmazás létrehozásához.
Hozzon létre egy új Python-projektet a Visual Studióban azÚj>projekt fájl> kiválasztásával.
Az Új projekt létrehozása párbeszédpanelen keressen Pythonra. Válassza ki a Python-alkalmazássablont , és válassza a Tovább gombot.
Adja meg a projekt nevét és helyét, és válassza a Létrehozás lehetőséget.
A Visual Studio létrehozza az új projektet. A projekt megnyílik a Megoldáskezelőben , a projektfájl (.py) pedig megnyílik a kódszerkesztőben.
Illessze be a következő kódot a .py fájlba. A Python egyes szerkesztési funkcióinak használatához próbálja meg manuálisan beírni a kódot.
Ez a kód egy hiperbolikus tangenst számít ki a matematikai kódtár használata nélkül, és ezt gyorsíthatja fel később a Python natív bővítményeivel.
Jótanács
Írja meg a kódot tiszta Pythonban, mielőtt újraírja a C++-ban. Így könnyebben ellenőrizheti, hogy a natív Python-kód helyes-e.
from random import random from time import perf_counter # Change the value of COUNT according to the speed of your computer. # The value should enable the benchmark to complete in approximately 2 seconds. COUNT = 500000 DATA = [(random() - 0.5) * 3 for _ in range(COUNT)] e = 2.7182818284590452353602874713527 def sinh(x): return (1 - (e ** (-2 * x))) / (2 * (e ** -x)) def cosh(x): return (1 + (e ** (-2 * x))) / (2 * (e ** -x)) def tanh(x): tanh_x = sinh(x) / cosh(x) return tanh_x def test(fn, name): start = perf_counter() result = fn(DATA) duration = perf_counter() - start print('{} took {:.3f} seconds\n\n'.format(name, duration)) for d in result: assert -1 <= d <= 1, " incorrect values" if __name__ == "__main__": print('Running benchmarks with COUNT = {}'.format(COUNT)) test(lambda d: [tanh(x) for x in d], '[tanh(x) for x in d] (Python implementation)')Futtassa a programot a Hibakeresési>indítás hibakeresés nélkül parancsával, vagy válassza a Ctrl+F5 billentyűparancsot.
Megnyílik egy parancsablak a program kimenetének megjelenítéséhez.
A kimenetben figyelje meg a referenciafolyamathoz jelentett időt.
Ehhez az útmutatóhoz a tesztfolyamatnak körülbelül 2 másodpercet kell igénybe vennie.
Szükség szerint módosítsa a változó értékét a
COUNTkódban, hogy a teljesítményteszt körülbelül 2 másodperc alatt befejeződhessen a számítógépen.Futtassa újra a programot, és győződjön meg arról, hogy a módosított
COUNTérték körülbelül 2 másodperc alatt létrehozza a teljesítménytesztet.
Jótanács
Teljesítménytesztek futtatásakor mindig használja a Hibakeresési>indítás hibakeresés nélkül lehetőséget. Ez a módszer segít elkerülni azokat a többletterheléseket, amelyek a kód Visual Studio hibakeresőn belüli futtatásakor merülhetnek fel.
Az alapvető C++ projektek létrehozása
Kövesse az alábbi lépéseket két azonos C++ projekt, a superfastcode és a superfastcode2 létrehozásához. Később minden projektben más-más módszerrel teheti elérhetővé a C++ kódot a Python számára.
A Megoldáskezelőben kattintson a jobb gombbal a megoldás nevére, és válassza azÚj projekt>.
A Visual Studio-megoldások Python- és C++-projekteket is tartalmazhatnak, ami a Visual Studio pythonos fejlesztésének egyik előnye.
Az Új projekt hozzáadása párbeszédpanelen állítsa a Nyelv szűrőt C++ értékre, és írja be üresen a Keresőmezőbe .
A projektsablon eredményeinek listájában válassza az Üres projekt, majd a Tovább lehetőséget.
Az új projekt konfigurálása párbeszédpanelen adja meg a projekt nevét:
- Az első projektnél adja meg a superfastcode nevet.
- A második projektnél adja meg a superfastcode2 nevet.
Válassza a Create gombot.
Mindenképpen ismételje meg ezeket a lépéseket, és hozzon létre két projektet.
Jótanács
Alternatív megközelítés akkor érhető el, ha a Python natív fejlesztői eszközei telepítve vannak a Visual Studióban. A Python Bővítménymodul sablonnal kezdheti, amely a cikkben ismertetett lépések nagy részét előre végrehajtja.
A cikkben ismertetett útmutatóban egy üres projekttől kezdve lépésről lépésre bemutatjuk, hogyan hozhatja létre a bővítménymodult. A folyamat megértése után a másik sablonnal időt takaríthat meg, amikor saját bővítményeket ír.
C++ fájl hozzáadása a projekthez
Ezután adjon hozzá egy C++ fájlt minden projekthez.
A Megoldáskezelőben bontsa ki a projektet, kattintson a jobb gombbal a Forrásfájlok csomópontra, és válassza azÚj elem> lehetőséget.
A fájlsablonok listájában válassza a C++ Fájl (.cpp) lehetőséget.
Adja meg a fájl nevétmodule.cpp, majd válassza a Hozzáadás lehetőséget.
Fontos
Győződjön meg arról, hogy a fájlnév tartalmazza a .cpp bővítményt. A Visual Studio egy .cpp kiterjesztésű fájlt keres a C++ projekttulajdonságok megjelenítésének engedélyezéséhez.
Az eszköztáron bontsa ki a Konfiguráció legördülő menüt, és válassza ki a célkonfiguráció típusát:
- 64 bites Python-futtatókörnyezet esetén aktiválja az x64-konfigurációt .
- 32 bites Python-futtatókörnyezet esetén aktiválja a Win32-konfigurációt .
Mindenképpen ismételje meg ezeket a lépéseket mindkét projekt esetében.
Projekttulajdonságok konfigurálása
Mielőtt kódot ad az új C++ fájlokhoz, konfigurálja az egyes C++ modulprojektek tulajdonságait, és tesztelje a konfigurációkat, hogy minden működjön.
Az egyes modulok hibakeresési és kiadási buildkonfigurációinak projekttulajdonságait is be kell állítania.
A Megoldáskezelőben kattintson a jobb gombbal a C++ modulprojektre (superfastcode vagy superfastcode2), és válassza a Tulajdonságok lehetőséget.
Konfigurálja a modul hibakeresési buildjének tulajdonságait, majd konfigurálja ugyanazokat a tulajdonságokat a kiadási buildhez:
A projekt tulajdonságlapjainak párbeszédpanel tetején konfigurálja a következő fájlkonfigurációs beállításokat:
A konfigurációhoz válassza a Hibakeresés vagy a Kiadás lehetőséget. (Ezeket a beállításokat az Aktív előtaggal láthatja.)
A platform esetében válassza az Aktív (x64) vagy az Aktív (Win32) lehetőséget az előző lépésben megadott beállítástól függően.
Megjegyzés:
Amikor saját projekteket hoz létre, a hibakeresési és kiadási konfigurációkat külön kell konfigurálnia az adott forgatókönyv követelményeinek megfelelően. Ebben a gyakorlatban a konfigurációkat a CPython kiadási buildjének használatára állítja be. Ez a konfiguráció letiltja a Microsoft Visual C++ futtatókörnyezet néhány hibakeresési funkcióját, beleértve az állításokat is. A CPython hibakeresési bináris fájljainak (python_d.exe) használata különböző beállításokat igényel.
Egyéb projekttulajdonságok beállítása az alábbi táblázatban leírtak szerint.
Tulajdonságérték módosításához írjon be egy értéket a tulajdonságmezőbe. Egyes mezők esetében az aktuális érték kiválasztásával kibonthatja a választási lehetőségek legördülő menüjét, vagy megnyithat egy párbeszédpanelt az érték meghatározásához.
Miután frissítette az értékeket egy lapon, válassza az Alkalmaz elemet, mielőtt másik lapra váltana. Ez a művelet segít biztosítani, hogy a módosítások megmaradjanak.
Lap és szakasz Ingatlan Érték Konfigurációs tulajdonságok>Általános Célnév Adja meg a modul nevét, amelyre a Pythonban hivatkozunk from...importutasításokban, például szupergyorskód. Ugyanezt a nevet használja a C++ kódban a Python moduljának definiálásakor. Ha a projekt nevét szeretné modulnévként használni, hagyja meg a $<ProjectName> alapértelmezett értékét. Adja a(z)python_d.exe-t hozzá_da név végéhez.Konfiguráció típusa Dinamikus kódtár (.dll) Konfigurációs tulajdonságok>Haladó Célfájl-bővítmény .pyd (Python-bővítménymodul) C/C++>Általános További tartalmazási könyvtárak Adja hozzá a Python include mappát a telepítéshez megfelelő módon (például c:\Python36\include). C/C++>Előfeldolgozó Preprocesszor-definíciók Ha jelen van, módosítsa a _DEBUG értékét NDEBUG értékre , hogy megfeleljen a CPython nem hibakeresési verziójának. Ha python_d.exehasznál, hagyja változatlanul ezt az értéket. C/C++>Kódgenerálás Futtatókörnyezeti kódtár Többszálas DLL (/MD) a CPython kiadási (nem hibakeresési) verziójának megfelelően. Ha python_d.exehasznál, hagyja meg ezt az értéket többszálú hibakeresési DLL-ként (/MDd). Alapszintű futtatókörnyezet-ellenőrzések Alapértelmezett Szerkesztő>Általános További könyvtárkönyvtárak Adja hozzá a .libfájlokat tartalmazó Python-libs mappát a telepítéshez megfelelő módon (például c:\Python36\libs). Mindenképpen mutasson arra a libs mappára, amely .lib fájlokat tartalmaz, ne pedig arra a Lib mappára, amely .py fájlokat tartalmaz. Fontos
Ha a C/C++ lap nem jelenik meg a projekt tulajdonságainak beállításaként, akkor a projekt nem tartalmaz olyan kódfájlokat, amelyeket a Visual Studio C/C++ forrásfájlként azonosít. Ez a feltétel akkor fordulhat elő, ha .c vagy .cpp kiterjesztés nélküli forrásfájlt hoz létre.
Ha véletlenül a module.coo értéket adta meg a C++ fájl létrehozásakor module.cpp helyett, a Visual Studio létrehozza a fájlt, de nem állítja be a fájltípust C/C+ fordítóra. Ez a fájltípus szükséges a C/C++ tulajdonságok lap jelenlétének aktiválásához a projekttulajdonságok párbeszédpanelen. A helytelenítés akkor is megmarad, ha átnevezi a kódfájlt egy .cpp fájlkiterjesztéssel.
A kódfájl típusának megfelelő beállításához a Megoldáskezelőben kattintson a jobb gombbal a kódfájlra, és válassza a Tulajdonságok lehetőséget. Az Elemtípushoz válassza a C/C++ fordítót.
Miután frissítette az összes tulajdonságot, válassza az OK gombot.
Ismételje meg a többi buildkonfiguráció lépéseit.
Tesztelje az aktuális konfigurációt. Ismételje meg a következő lépéseket mindkét C++ projekt hibakeresési és kiadási buildjeihez.
Kód és tesztkonfiguráció hozzáadása
Most már készen állsz a C++ fájlok kódjának hozzáadására és a kiadási változat tesztelésére.
A C++ szupergyors kód esetében nyissa meg a module.cpp fájlt a kódszerkesztőben.
Illessze be a következő kódot a module.cpp fájlba:
#include <Windows.h> #include <cmath> const double e = 2.7182818284590452353602874713527; double sinh_impl(double x) { return (1 - pow(e, (-2 * x))) / (2 * pow(e, -x)); } double cosh_impl(double x) { return (1 + pow(e, (-2 * x))) / (2 * pow(e, -x)); } double tanh_impl(double x) { return sinh_impl(x) / cosh_impl(x); }Mentse a módosításokat.
Hozza létre a C++ projekt kiadási konfigurációját, hogy meggyőződjön a kód helyességéről.
Ismételje meg a lépéseket a superfastcode2 projekt C++ fájljának kódjának hozzáadásához és a kiadás buildjének teszteléséhez .
C++ projektek konvertálása Python-bővítményekké
Ha a C++ DLL-t Python-bővítményként szeretné használni, először módosítsa az exportált metódusokat a Python-típusok használatához. Ezután adjon hozzá egy függvényt a modul exportálásához, valamint a modul metódusainak definícióit.
A következő szakaszok bemutatják, hogyan hozhatja létre a bővítményeket a CPython-bővítmények és a PyBind11 használatával. A superfasctcode projekt a CPython-bővítményeket használja, a superfasctcode2 projekt pedig a PyBind11-et implementálja.
CPython-bővítmények használata
Az ebben a szakaszban bemutatott kódról további információt a Python/C API referencia-kézikönyvében talál, különösen a Modulobjektumok lapon. Amikor áttekinti a referenciatartalmat, mindenképpen válassza ki a Python verzióját a jobb felső legördülő listában.
A C++ szupergyors kód esetében nyissa meg a module.cpp fájlt a kódszerkesztőben.
Adjon hozzá egy utasítást a module.cpp fájl tetején a Python.h fejlécfájl hozzáadásához:
#include <Python.h>Cserélje le a
tanh_implmetóduskódot úgy, hogy az Python-típusokat fogadjon el és adjon vissza (azaz egyPyObject*).PyObject* tanh_impl(PyObject* /* unused module reference */, PyObject* o) { double x = PyFloat_AsDouble(o); double tanh_x = sinh_impl(x) / cosh_impl(x); return PyFloat_FromDouble(tanh_x); }A fájl végén adjon hozzá egy struktúrát, amely meghatározza a C++
tanh_implfüggvény Pythonban való bemutatását:static PyMethodDef superfastcode_methods[] = { // The first property is the name exposed to Python, fast_tanh // The second is the C++ function with the implementation // METH_O means it takes a single PyObject argument { "fast_tanh", (PyCFunction)tanh_impl, METH_O, nullptr }, // Terminate the array with an object containing nulls { nullptr, nullptr, 0, nullptr } };Adjon hozzá egy másik struktúrát, amely meghatározza, hogyan hivatkozhat a modulra a Python-kódban, különösen az
from...importutasítás használatakor.A kódban importált névnek meg kell egyeznie a konfigurációs tulajdonságok>> területen található projekttulajdonságok értékével.
Az alábbi példában a
"superfastcode"név arra utal, hogy afrom superfastcode import fast_tanhutasítást használhatja a Pythonban, mert afast_tanhmeg van határozva asuperfastcode_methods-ben. A C++ projekt belső fájlnevei (például module.cpp) jelentéktelenek.static PyModuleDef superfastcode_module = { PyModuleDef_HEAD_INIT, "superfastcode", // Module name to use with Python import statements "Provides some functions, but faster", // Module description 0, superfastcode_methods // Structure that defines the methods of the module };Adjon hozzá egy metódust, amelyet a Python a modul betöltésekor hív meg. A metódusnévnek olyannak kell lennie
PyInit_<module-name>, ahol <a modul neve> pontosan megegyezik a C++ projekt Konfigurációs tulajdonságok>általános>célnév tulajdonságával. Vagyis a metódus neve megegyezik a projekt által létrehozott .pyd fájl nevével.PyMODINIT_FUNC PyInit_superfastcode() { return PyModule_Create(&superfastcode_module); }Hozza létre a C++ projektet, és ellenőrizze a kódot. Ha hibákba ütközik, olvassa el a fordítási hibák elhárítása című szakaszt .
Használja a PyBind11-et
Ha végrehajtja a szupergyors kód projekt előző szakaszának lépéseit, észreveheti, hogy a gyakorlathoz szükség van egy sablonkódra a C++ CPython-bővítmények modulstruktúráinak létrehozásához. Ebben a gyakorlatban felfedezheti, hogy a PyBind11 leegyszerűsíti a kódolási folyamatot. A C++ fejlécfájlban lévő makrókkal ugyanazt az eredményt érheti el, de sokkal kevesebb kóddal. További lépésekre azonban szükség van annak biztosításához, hogy a Visual Studio megkeresse a PyBind11-kódtárakat, és fájlokat is tartalmazzon. A jelen szakaszban található kódról további információt a PyBind11 alapjai című témakörben talál.
A PyBind11 telepítése
Az első lépés a PyBind11 telepítése a projektkonfigurációban. Ebben a gyakorlatban a Fejlesztői PowerShell-ablakot használja.
Nyissa meg az Eszközök>parancssori>fejlesztői PowerShell-ablakot .
A Developer PowerShell ablakban telepítse a PyBind11-et a pip paranccsal
pip install pybind11vagypy -m pip install pybind11a .A Visual Studio telepíti a PyBind11-et és annak függő csomagjait.
PyBind11-útvonalak hozzáadása a projekthez
A PyBind11 telepítése után hozzá kell adnia a PyBind11 elérési útjait a projekt További belefoglalási könyvtárak tulajdonságához.
A PowerShell Developer ablakban futtassa a
python -m pybind11 --includesvagypy -m pybind11 --includesparancsot.Ez a művelet kinyomtatja a projekttulajdonságokhoz hozzáadni kívánt PyBind11 elérési utak listáját.
Jelölje ki az ablakban az elérési utak listáját, és válassza a Másolás (dupla oldal) lehetőséget az ablak eszköztárán.
Az összefűzött útvonalak listája hozzáadódik a vágólaphoz.
A Megoldáskezelőben kattintson a jobb gombbal a superfastcode2 projektre, és válassza a Tulajdonságok lehetőséget.
A Tulajdonságlapok párbeszédpanel tetején a Konfiguráció mezőnél válassza a Kiadás lehetőséget. (Ez a beállítás az Aktív előtaggal jelenhet meg.)
A párbeszédpanel C/C++>Általános lapján bontsa ki a További include könyvtárak tulajdonság legördülő menüjét, és válassza a Szerkesztés lehetőséget.
Az előugró párbeszédpanelen adja hozzá a másolt elérési utak listáját:
Ismételje meg az alábbi lépéseket a Fejlesztői PowerShell ablakból kimásolt összefűzött lista egyes elérési útjaihoz:
Válassza az Új sor (plusz szimbólummal ellátott mappa ikont) az előugró párbeszédpanel eszköztárán.
A Visual Studio egy üres sort ad hozzá az elérési utak listájának tetején, és a kurzort az elején helyezi el.
Illessze be a PyBind11 elérési útját az üres sorba.
A További beállítások (...) lehetőséget is választhatja, és egy előugró fájlkezelő párbeszédpanel használatával megkeresheti az elérési utat.
Fontos
- Ha az elérési út tartalmazza az
-Ielőtagot, távolítsa el az előtagot az elérési útból. - Ahhoz, hogy a Visual Studio felismerjen egy útvonalat, az elérési útnak külön sorban kell lennie.
Az új elérési út hozzáadása után a Visual Studio megjeleníti a megerősített elérési utat a Kiértékelt érték mezőben.
- Ha az elérési út tartalmazza az
Válassza az OK gombot az előugró párbeszédpanel bezárásához.
A Tulajdonságlapok párbeszédpanel tetején vigye az egérmutatót a További belefoglalási könyvtárak tulajdonság értéke fölé, és győződjön meg arról, hogy a PyBind11 elérési útjai megtalálhatók.
Válassza az OK gombot a tulajdonságmódosítások alkalmazásához.
A module.cpp fájl frissítése
Az utolsó lépés a PyBind11 fejlécfájl és makrókód hozzáadása a C++ projektfájlhoz.
A superfastcode2 C++ projekt esetében nyissa meg a module.cpp fájlt a kódszerkesztőben.
Adjon hozzá egy utasítást a module.cpp fájl tetején a pybind11.h fejlécfájl hozzáadásához:
#include <pybind11/pybind11.h>A module.cpp fájl végén adja hozzá a makró kódját a
PYBIND11_MODULEC++ függvény belépési pontjának meghatározásához:namespace py = pybind11; PYBIND11_MODULE(superfastcode2, m) { m.def("fast_tanh2", &tanh_impl, R"pbdoc( Compute a hyperbolic tangent of a single argument expressed in radians. )pbdoc"); #ifdef VERSION_INFO m.attr("__version__") = VERSION_INFO; #else m.attr("__version__") = "dev"; #endif }Hozza létre a C++ projektet, és ellenőrizze a kódot. Ha hibákba ütközik, tekintse meg a következő, fordítási hibák elhárítása című szakaszt.
Fordítási hibák elhárítása
Tekintse át az alábbi szakaszokat az olyan lehetséges problémákról, amelyek a C++ modul buildjének sikertelenségéhez vezethetnek.
Hiba: Nem található a fejlécfájl
A Visual Studio egy olyan hibaüzenetet ad vissza, mint az E1696: Nem lehet megnyitni a "Python.h" vagy a C1083 forrásfájlt: Nem nyitható meg a következő fájl: "Python.h": Nincs ilyen fájl vagy könyvtár.
Ez a hiba azt jelzi, hogy a fordító nem találja a projekthez szükséges fejlécfájlt (.h).
A szupergyors kódú projekt esetében ellenőrizze, hogy a C/C++>Általános>további belefoglalási könyvtárak projekttulajdonság tartalmazza-e a Python-telepítés belefoglalási mappájának elérési útját. Tekintse át a projekttulajdonságok konfigurálásához szükséges lépéseket.
A superfastcode2 projekt esetében ellenőrizze, hogy ugyanaz a projekttulajdonság tartalmazza-e a PyBind11 telepítés belefoglalási mappájának elérési útját. Tekintse át a(z) PyBind útvonalak projektbe történő hozzáadásának lépéseit.
A Python telepítési konfigurációs adatainak eléréséről további információt a Python dokumentációjában talál.
Hiba: Nem található a Python-kódtárak
A Visual Studio hibát ad vissza, amely azt jelzi, hogy a fordító nem találja a projekthez szükséges kódtárfájlokat (DLL-fájlokat).
- A C++ projekt (superfastcode vagy superfastcode2) esetében ellenőrizze, hogy a Linker>Általános>további könyvtárkönyvtárak tulajdonság tartalmazza-e a Python-telepítés libs mappájának elérési útját. Tekintse át a projekttulajdonságok konfigurálásához szükséges lépéseket.
A Python telepítési konfigurációs adatainak eléréséről további információt a Python dokumentációjában talál.
A célarchitektúra linkerhibái
A Visual Studio jelentést készít a projekt célarchitektúra-beállításaival kapcsolatos linker hibákról, mint amilyen az x64 vagy a Win32.
- A C++ projekt (superfastcode vagy superfastcode2) esetében módosítsa a célkonfigurációt úgy, hogy megfeleljen a Python-telepítésnek. Ha például a C++ projekt célkonfigurációja Win32, de a Python-telepítés 64 bites, módosítsa a C++ projektcél konfigurációját x64-re.
A kód tesztelése és az eredmények összehasonlítása
Most, hogy a DLL-ek Python-bővítményekként vannak strukturálva, hivatkozhat rájuk a Python-projektből, importálhatja a modulokat, és használhatja a metódusaikat.
A DLL elérhetővé tétele a Python számára
A DLL-t többféleképpen is elérhetővé teheti a Python számára. Az alábbiakban két lehetőséget érdemes figyelembe venni:
Ha a Python-projekt és a C++ projekt ugyanabban a megoldásban van, a következő megközelítést használhatja:
A Megoldáskezelőben kattintson a jobb gombbal a Python-projekt Hivatkozások csomópontjára, és válassza a Hivatkozás hozzáadása lehetőséget.
Ezt a műveletet ne a C++ projekthez, hanem a Python-projekthez végezze el.
A Hivatkozás hozzáadása párbeszédpanelen bontsa ki a Projektek lapot.
Jelölje be a superfastcode és a superfastcode2 projektek jelölőnégyzeteit, majd kattintson az OK gombra.
Másik módszer a C++ bővítménymodul telepítése a Python-környezetben. Ez a módszer elérhetővé teszi a modult más Python-projektek számára. További információ: setuptools projektdokumentáció.
A C++ bővítménymodul Python-környezetben való telepítéséhez hajtsa végre az alábbi lépéseket:
A Megoldáskezelőben kattintson a jobb gombbal a C++ projektre, és válassza azÚj elem>.
A fájlsablonok listájában válassza a C++ Fájl (.cpp) lehetőséget.
Adja meg a fájl nevétsetup.py, majd válassza a Hozzáadás lehetőséget.
Mindenképpen adja meg a fájlnevet a Python (.py) kiterjesztéssel. A Visual Studio a C++ fájlsablon használata ellenére Python-kódként ismeri fel a fájlt.
A Visual Studio megnyitja az új fájlt a kódszerkesztőben.
Illessze be a következő kódot az új fájlba. Válassza ki a bővítménymetódusnak megfelelő kódverziót:
CPython-bővítmények (superfastcode projekt):
from setuptools import setup, Extension sfc_module = Extension('superfastcode', sources = ['module.cpp']) setup( name='superfastcode', version='1.0', description='Python Package with superfastcode C++ extension', ext_modules=[sfc_module] )PyBind11 (superfastcode2 projekt):
from setuptools import setup, Extension import pybind11 cpp_args = ['-std=c++11', '-stdlib=libc++', '-mmacosx-version-min=10.7'] sfc_module = Extension( 'superfastcode2', sources=['module.cpp'], include_dirs=[pybind11.get_include()], language='c++', extra_compile_args=cpp_args, ) setup( name='superfastcode2', version='1.0', description='Python package with superfastcode2 C++ extension (PyBind11)', ext_modules=[sfc_module], )
A C++ projektben hozzon létre egy második fájlt pyproject.toml néven, és illessze be a következő kódot:
[build-system] requires = ["setuptools", "wheel", "pybind11"] build-backend = "setuptools.build_meta"A TOML (.toml) fájl a Tom nyilvánvaló, minimális nyelvi formátumát használja a konfigurációs fájlokhoz.
A bővítmény létrehozásához kattintson a jobb gombbal a pyproject.toml fájlnévre a kódablak lapján, és válassza a Teljes elérési út másolása lehetőséget.
Használat előtt törölje a pyproject.toml nevet az elérési útból.
A Megoldáskezelőbenbontsa ki a megoldásHoz tartozó Python-környezetek csomópontot.
Kattintson a jobb gombbal az aktív Python-környezetre (félkövér színben jelenik meg), és válassza a Python-csomagok kezelése lehetőséget.
Megnyílik a Python-környezetek panel.
Ha a szükséges csomag már telepítve van, az ezen a panelen látható.
- A folytatás előtt válassza a csomag neve melletti X elemet az eltávolításhoz.
A Python-környezetek panel keresőmezőjében illessze be a másolt elérési utat, és törölje a pyproject.toml fájlnevet az elérési út végéről.
Az Enter elemet választva telepítse a modult a másolt elérési út helyére.
Jótanács
Ha a telepítés engedélyhiba miatt meghiúsul, adja hozzá az
--userargumentumot a parancs végéhez, és próbálkozzon újra a telepítéssel.
A DLL meghívása Pythonból
Miután a DLL-t elérhetővé tette a Python számára az előző szakaszban leírtak szerint, készen áll arra, hogy a superfastcode.fast_tanh és superfastcode2.fast_tanh2 függvényeket meghívja Pythonból. Ezután összehasonlíthatja a függvény teljesítményét a Python-implementációval.
Kövesse az alábbi lépéseket a bővítménymodul DLL-jének meghívásához a Pythonból:
Nyissa meg a Python-projekt .py fájlját a kódszerkesztőben.
A fájl végén adja hozzá a következő kódot a DLL-ekből exportált metódusok meghívásához és a kimenetük megjelenítéséhez:
from superfastcode import fast_tanh test(lambda d: [fast_tanh(x) for x in d], '[fast_tanh(x) for x in d] (CPython C++ extension)') from superfastcode2 import fast_tanh2 test(lambda d: [fast_tanh2(x) for x in d], '[fast_tanh2(x) for x in d] (PyBind11 C++ extension)')Python-program futtatásához válassza a Debug>Hibakeresés nélkül indítás, vagy használja a Ctrl+F5 billentyűparancsot.
Megjegyzés:
Ha a Hibakeresés nélkül parancs nem érhető el, a Megoldáskezelőben kattintson a jobb gombbal a Python-projektre, majd válassza a Beállítás indítási projektként lehetőséget.
A program végrehajtásakor figyelje meg, hogy a C++ rutinok körülbelül 5-20-szor gyorsabban futnak, mint a Python-implementáció.
Íme egy példa a program tipikus kimenetére:
Running benchmarks with COUNT = 500000 [tanh(x) for x in d] (Python implementation) took 0.758 seconds [fast_tanh(x) for x in d] (CPython C++ extension) took 0.076 seconds [fast_tanh2(x) for x in d] (PyBind11 C++ extension) took 0.204 secondsPróbálja meg növelni a változót
COUNT, hogy az időkülönbségek hangsúlyosabbak legyenek.A C++ modul hibakeresési buildje is lassabban fut, mint egy kiadási build, mivel a hibakeresési build kevésbé optimalizált, és különböző hibaellenőrzéseket tartalmaz. Próbáljon meg váltani a buildkonfigurációk között összehasonlítás céljából, de ne felejtse el frissíteni a kiadási konfigurációhoz korábban beállított tulajdonságokat.
A folyamat sebességének és többletterhelésének kezelése
A kimenetben észreveheti, hogy a PyBind11 bővítmény nem olyan gyors, mint a CPython bővítmény, bár gyorsabbnak kell lennie a tiszta Python-implementációnál. A különbség fő oka a METH_O jelző használata. Ez a jelző nem támogat több paramétert, paraméternevet vagy kulcsszóargumentumot. A PyBind11 valamivel összetettebb kódot hoz létre, hogy Python-szerű felületet biztosítson a hívóknak. Mivel a tesztkód 500 000-szer hívja meg a függvényt, az eredmények jelentősen felerősíthetik a többletterhelést.
A többletterhelést tovább csökkentheti a for hurok natív Python-kódba való áthelyezésével. Ebben a megközelítésben az iterátorprotokoll (vagy a py::iterable PyBind11 típusa) használatával kell feldolgozni az egyes elemeket. A Python és a C++ közötti ismétlődő átmenetek eltávolítása hatékony módszer a sorozat feldolgozásához szükséges idő csökkentésére.
Importálási hibák elhárítása
Ha a modul importálása során üzenetet ImportError kap, az alábbi módok egyikével oldhatja fel:
Amikor projekthivatkozáson keresztül készíti el a projektet, győződjön meg arról, hogy a C++ projekttulajdonságok megegyeznek a Python-projekthez aktivált Python-környezettel. Ellenőrizze, hogy ugyanazok a mappahelyek vannak-e használatban az Include (.h) és a Library (DLL) fájlokhoz.
Győződjön meg arról, hogy a kimeneti fájl neve helyes, például superfastcode.pyd. A helytelen név vagy bővítmény megakadályozza a szükséges fájl importálását.
Ha a modult a setup.py fájllal telepíti, mindenképpen futtassa a
pipparancsot a Python-projekthez aktivált Python-környezetben. Amikor kibontja a projekt aktív Python-környezetét a Megoldáskezelőben, látnia kell egy bejegyzést a C++ projekthez, például a szupergyors kódhoz.
C++ kód hibakeresése
A Visual Studio támogatja a Python és a C++ kód együttes hibakeresését. Az alábbi lépések a C++ szupergyors kódú projekt hibakeresési folyamatát mutatják be, de a superfastcode2 projekt esetében ugyanaz a folyamat.
A Megoldáskezelőben kattintson a jobb gombbal a Python-projektre, és válassza a Tulajdonságok lehetőséget.
A Tulajdonságok panelen válassza a Hibakeresés lapot, majd válassza a Hibakeresés>engedélyezése natív kód hibakeresésének engedélyezése lehetőséget.
Jótanács
Ha engedélyezi a natív kódszintű hibakeresést, a Python kimeneti ablak azonnal bezárulhat, miután a program befejeződött, és nem jelenik meg a Nyomjon meg egy gombot a folytatáshoz üzenet. Ha a natív kód hibakeresésének engedélyezése után szeretné kényszeríteni a szüneteltetést és a kérést, adja hozzá az
-iargumentumot a Hibakeresés lap>futtatása mezőjéhez. Ez az argumentum interaktív módba helyezi a Python-értelmezőt a kód futtatása után. A program megvárja, amíg kiválasztja Ctrl+Z+Enter billentyűkombinációt az ablak bezárásához. Egy alternatív megközelítés az, hogy aimport osésos.system("pause")utasításokat a Python-program végére helyezzük. Ez a kód duplikálja az eredeti szüneteltetés kérését.A tulajdonság módosításainak mentéséhez válassza a Fájl>mentése (vagy Ctrl+S) lehetőséget.
A Visual Studio eszköztárán állítsa a buildkonfigurációt hibakeresésre.
Mivel a kód futtatása általában hosszabb időt vesz igénybe a hibakeresőben, érdemes lehet módosítani a
COUNTPython-projekt változóját .py fájlban az alapértelmezett értéknél körülbelül ötször kisebb értékre. Módosítsa például 5000000-ről100000-re.A C++ kódban állítson be egy töréspontot a
tanh_implmetódus első sorára.Indítsa el a hibakeresőt a Hibakeresés>indítása lehetőség kiválasztásával vagy az F5 billentyűparancs használatával.
A hibakereső leáll a töréspont-kód meghívásakor. Ha a töréspontot nem éri el, ellenőrizze, hogy a konfiguráció hibakeresésre van-e beállítva, és hogy mentette-e a projektet, ami nem történik meg automatikusan a hibakereső indításakor.
A törésponton végiglépkedhet a C++ kódon, megvizsgálhatja a változókat stb. További információ ezekről a funkciókról: Python és C++ együttes hibakeresése.
Alternatív megoldások
Python-bővítményeket többféleképpen is létrehozhat, az alábbi táblázatban leírtak szerint. Az első két sort, CPython és PyBind11ebben a cikkben tárgyaljuk.
| Megközelítés | Hagyományos | Reprezentatív felhasználók |
|---|---|---|
C/C++ bővítménymodulok a következőhöz: CPython |
1991 | Standard könyvtár |
| PyBind11 (C++-hoz ajánlott) | 2015 | |
| Cython (C esetén ajánlott) | 2007 | gevent, kivy |
| HPy | 2019 | |
| mypyc | 2017 | |
| ctypes | 2003 | oscrypto |
| cffi | 2013 | titkosítás, pypy |
| SWIG | 1996 | crfsuite |
| Boost.Python | 2002 | |
| cppyy | 2017 |