Megosztás a következőn keresztül:


C++ bővítmény létrehozása Pythonhoz a Visual Studióban

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 CPython futtató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 CPython leí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.

    Képernyőkép a Python fejlesztési lehetőségeinek listájáról, kiemelve a Python natív fejlesztési eszközeit.

    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.

  1. Hozzon létre egy új Python-projektet a Visual Studióban azÚj>projekt fájl> kiválasztásával.

  2. 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.

  3. 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.

  4. 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)')
    
  5. 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.

  6. 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.

  7. Szükség szerint módosítsa a változó értékét a COUNT kódban, hogy a teljesítményteszt körülbelül 2 másodperc alatt befejeződhessen a számítógépen.

  8. 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.

  1. 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.

  2. 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 .

  3. A projektsablon eredményeinek listájában válassza az Üres projekt, majd a Tovább lehetőséget.

  4. 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.
  5. 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.

  1. 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.

  2. A fájlsablonok listájában válassza a C++ Fájl (.cpp) lehetőséget.

  3. 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.

  4. 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:

    Képernyőkép a C++ projekt célkonfigurációs típusának a Visual Studióban való beállításáról.

    • 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.

  1. A Megoldáskezelőben kattintson a jobb gombbal a C++ modulprojektre (superfastcode vagy superfastcode2), és válassza a Tulajdonságok lehetőséget.

  2. 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:

    Képernyőkép arról, hogyan állíthatja be a projekt buildelési és platformbeállítását a C++ fájlhoz a Visual Studióban.

    1. 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.)

    2. 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.

    3. 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...import utasí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á _d a 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.

    4. Miután frissítette az összes tulajdonságot, válassza az OK gombot.

    Ismételje meg a többi buildkonfiguráció lépéseit.

  3. 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.

    1. A Visual Studio eszköztárán állítsa a buildkonfigurációt hibakeresésre vagy kiadásra:

      Képernyőkép a C++ projekt buildkonfigurációjának a Visual Studióban való beállításáról.

    2. A Megoldáskezelőben kattintson a jobb gombbal a C++ projektre, és válassza a Build lehetőséget.

      A .pyd fájlok a Megoldás mappában, a Hibakeresés és a Kiadás csoportban találhatók, és nem a C++ projektmappában.

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.

  1. A C++ szupergyors kód esetében nyissa meg a module.cpp fájlt a kódszerkesztőben.

  2. 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);
    }
    
  3. Mentse a módosításokat.

  4. 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.

  1. A C++ szupergyors kód esetében nyissa meg a module.cpp fájlt a kódszerkesztőben.

  2. 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>
    
  3. Cserélje le a tanh_impl metóduskódot úgy, hogy az Python-típusokat fogadjon el és adjon vissza (azaz egy PyObject*).

    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);
    }
    
  4. A fájl végén adjon hozzá egy struktúrát, amely meghatározza a C++ tanh_impl fü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 }
    };
    
  5. 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...import utasí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 a from superfastcode import fast_tanh utasítást használhatja a Pythonban, mert a fast_tanh meg van határozva a superfastcode_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
    };
    
  6. 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);
    }
    
  7. 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.

  1. Nyissa meg az Eszközök>parancssori>fejlesztői PowerShell-ablakot .

  2. A Developer PowerShell ablakban telepítse a PyBind11-et a pip paranccsal pip install pybind11 vagy py -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.

  1. A PowerShell Developer ablakban futtassa a python -m pybind11 --includes vagy py -m pybind11 --includes parancsot.

    Ez a művelet kinyomtatja a projekttulajdonságokhoz hozzáadni kívánt PyBind11 elérési utak listáját.

  2. 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.

    Képernyőkép arról, hogyan emelheti ki és másolhatja ki az elérési utak listáját a Visual Studio Fejlesztői PowerShell ablakából.

    Az összefűzött útvonalak listája hozzáadódik a vágólaphoz.

  3. A Megoldáskezelőben kattintson a jobb gombbal a superfastcode2 projektre, és válassza a Tulajdonságok lehetőséget.

  4. 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.)

  5. 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.

  6. 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:

    1. Válassza az Új sor (plusz szimbólummal ellátott mappa ikont) az előugró párbeszédpanel eszköztárán.

      Képernyőkép arról, hogyan adhat hozzá PyBind11 elérési utat a További tartalmazási könyvtárak tulajdonsághoz.

      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.

    2. 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 -I elő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.

  7. Válassza az OK gombot az előugró párbeszédpanel bezárásához.

  8. 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.

  9. 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.

  1. A superfastcode2 C++ projekt esetében nyissa meg a module.cpp fájlt a kódszerkesztőben.

  2. 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>
    
  3. A module.cpp fájl végén adja hozzá a makró kódját a PYBIND11_MODULE C++ 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
    }
    
  4. 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 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:

  1. 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.

  2. A Hivatkozás hozzáadása párbeszédpanelen bontsa ki a Projektek lapot.

  3. Jelölje be a superfastcode és a superfastcode2 projektek jelölőnégyzeteit, majd kattintson az OK gombra.

    Képernyőkép arról, hogyan adhat hozzá hivatkozást a Visual Studióban a szupergyors kódprojekthez.

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:

  1. A Megoldáskezelőben kattintson a jobb gombbal a C++ projektre, és válassza azÚj elem>.

  2. A fájlsablonok listájában válassza a C++ Fájl (.cpp) lehetőséget.

  3. 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.

  4. 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],
      )
      
  5. 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.

  6. 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.

    Képernyőkép arról, hogyan másolhatja a teljes elérési utat a py project toml fájlba a Visual Studióban.

    Használat előtt törölje a pyproject.toml nevet az elérési útból.

  7. A Megoldáskezelőbenbontsa ki a megoldásHoz tartozó Python-környezetek csomópontot.

  8. 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.

    Képernyőkép egy csomag eltávolításáról a Python-környezetek panelen.

  9. 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.

    Képernyőkép arról, hogyan adhatja meg az elérési utat a Python-környezetek panelen a bővítménymodul telepítéséhez.

  10. 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 --user argumentumot 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:

  1. Nyissa meg a Python-projekt .py fájlját a kódszerkesztőben.

  2. 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)')
    
  3. 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 seconds
    
  4. Pró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 pip parancsot 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.

  1. A Megoldáskezelőben kattintson a jobb gombbal a Python-projektre, és válassza a Tulajdonságok lehetőséget.

  2. 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 -i argumentumot 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 a import os és os.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.

  3. A tulajdonság módosításainak mentéséhez válassza a Fájl>mentése (vagy Ctrl+S) lehetőséget.

  4. A Visual Studio eszköztárán állítsa a buildkonfigurációt hibakeresésre.

  5. Mivel a kód futtatása általában hosszabb időt vesz igénybe a hibakeresőben, érdemes lehet módosítani a COUNT Python-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.

  6. A C++ kódban állítson be egy töréspontot a tanh_impl metódus első sorára.

  7. 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.

    Képernyőkép a Visual Studióban töréspontot tartalmazó C++ kódról.

  8. 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