Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I den här artikeln skapar du en C++-tilläggsmodul för CPython för att beräkna en hyperbolisk tangent och anropa den från Python-kod. Rutinen implementeras först i Python för att demonstrera den relativa prestandavinsten för att implementera samma rutin i C++.
Kodmoduler skrivna i C++ (eller C) används ofta för att utöka funktionerna i en Python-tolk. Det finns tre primära typer av tilläggsmoduler:
- Acceleratormoduler: Aktivera snabbare prestanda. Eftersom Python är ett tolkat språk kan du skriva en acceleratormodul i C++ för högre prestanda.
- Omslutningsmoduler: Exponera befintliga C/C++-gränssnitt för Python-kod eller exponera ett mer Python-liknande API som är enkelt att använda från Python.
-
Systemåtkomstmoduler på låg nivå: Skapa systemåtkomstmoduler för att nå funktioner på lägre nivå i körningen
CPython
, operativsystemet eller den underliggande maskinvaran.
Den här artikeln visar två sätt att göra en C++-tilläggsmodul tillgänglig för Python:
- Använd standardtilläggen
CPython
enligt beskrivningen i Python-dokumentationen. - Använd PyBind11, som vi rekommenderar för C++11 på grund av dess enkelhet. Kontrollera att du arbetar med en av de nyare versionerna av Python för att säkerställa kompatibilitet.
Det färdiga exemplet för den här genomgången är tillgängligt på GitHub på python-samples-vs-cpp-extension.
Förutsättningar
Visual Studio 2017 eller senare med Python-utvecklingsarbetsbelastningen installerad. Arbetsbelastningen innehåller python-inbyggda utvecklingsverktyg, som lägger till C++-arbetsbelastningen och verktygsuppsättningarna som krävs för inbyggda tillägg.
Mer information om installationsalternativen finns i Installera Python-stöd för Visual Studio.
Anmärkning
När du installerar arbetsbelastningen datavetenskaps- och analysprogram installeras Python och alternativet för inbyggda utvecklingsverktyg i Python som standard.
Om du installerar Python separat måste du välja Ladda ned felsökningssymboler under Avancerade alternativ i Python-installationsprogrammet. Det här alternativet krävs för att du ska kunna använda felsökning i blandat läge mellan Python-koden och den interna koden.
Skapa Python-programmet
Följ de här stegen för att skapa Python-programmet.
Skapa ett nytt Python-projekt i Visual Studio genom att välja Nytt filprojekt>>.
I dialogrutan Skapa ett nytt projekt söker du efter python. Välj Python-mallen och klicka på Nästa.
Ange ett projektnamn och en plats och välj Skapa.
Visual Studio skapar det nya projektet. Projektet öppnas i Solution Explorer och projektfilen (.py) öppnas i kodredigeraren.
I filen .py klistrar du in följande kod. Om du vill uppleva några av Python-redigeringsfunktionerna kan du prova att ange koden manuellt.
Den här koden beräknar en hyperbolisk tangens utan att använda matematikbiblioteket, och det är det du påskyndar senare med inbyggda Python-tillägg.
Tips/Råd
Skriv koden i ren Python innan du skriver om den i C++. På så sätt kan du enklare kontrollera att din interna Python-kod är korrekt.
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)')
Kör programmet genom att välja Felsöka>Starta utan att felsöka eller välja kortkommandot Ctrl+F5.
Ett kommandofönster öppnas för att visa programmets utdata.
Lägg märke till tiden som rapporterats för benchmark-processen i resultatet.
För den här genomgången bör benchmark-processen ta cirka 2 sekunder.
Vid behov justerar du värdet för variabeln
COUNT
i koden så att benchmark-värdet kan slutföras om cirka 2 sekunder på datorn.Kör programmet igen och bekräfta att det ändrade
COUNT
värdet genererar riktmärket på cirka 2 sekunder.
Tips/Råd
När du kör benchmarks använder du alltid alternativet Felsök>start utan felsökning . Den här metoden hjälper till att undvika de omkostnader som kan uppstå när du kör koden i Visual Studio-felsökningsprogrammet.
Skapa C++-kärnprojekten
Följ dessa steg för att skapa två identiska C++-projekt, superfastcode och superfastcode2. Senare använder du en annan metod i varje projekt för att exponera C++-koden för Python.
Högerklicka på lösningsnamnet i Solution Explorer och välj Lägg till>nytt projekt.
En Visual Studio-lösning kan innehålla både Python- och C++-projekt, vilket är en av fördelarna med att använda Visual Studio för Python-utveckling.
I dialogrutan Lägg till ett nytt projekt anger du språkfiltret till C++ och anger tomti sökrutan .
I listan över projektmallsresultat väljer du Tomt projekt och sedan Nästa.
I dialogrutan Konfigurera det nya projektet anger du projektnamnet:
- För det första projektet anger du namnet superfastcode.
- För det andra projektet anger du namnet superfastcode2.
Välj Skapa.
Se till att upprepa de här stegen och skapa två projekt.
Tips/Råd
En alternativ metod är tillgänglig när du har python-inbyggda utvecklingsverktyg installerade i Visual Studio. Du kan börja med python-tilläggsmodulmallen , som i förväg slutför många av de steg som beskrivs i den här artikeln.
För genomgången i den här artikeln hjälper start med ett tomt projekt till att visa hur du skapar tilläggsmodulen steg för steg. När du har förstått processen kan du använda den alternativa mallen för att spara tid när du skriver egna tillägg.
Lägga till C++-fil i projektet
Lägg sedan till en C++-fil i varje projekt.
Expandera projektet i Solution Explorer, högerklicka på noden Källfiler och välj Lägg till>nytt objekt.
I listan över filmallar väljer du C++-fil (.cpp).
Ange namnet på filen som module.cpp och välj sedan Lägg till.
Viktigt!
Kontrollera att filnamnet innehåller .cpp-tillägget . Visual Studio letar efter en fil med .cpp-tillägget för att aktivera visning av C++-projektegenskapssidorna.
I verktygsfältet expanderar du listrutan Konfiguration och väljer din målkonfigurationstyp:
- Aktivera x64-konfigurationen för en 64-bitars Python-körning.
- Aktivera Win32-konfigurationen för en 32-bitars Python-körning.
Se till att upprepa de här stegen för båda projekten.
Konfigurera projektegenskaper
Innan du lägger till kod i de nya C++-filerna konfigurerar du egenskaperna för varje C++-modulprojekt och testar konfigurationerna för att kontrollera att allt fungerar.
Du måste ange projektegenskaperna för både debug och release byggregler för varje modul.
Högerklicka på C++-modulprojektet (superfastcode eller superfastcode2) i Solution Explorer och välj Egenskaper.
Konfigurera egenskaperna för felsökningsversionen av modulen och konfigurera sedan samma egenskaper för versionsversionen :
Konfigurera följande filkonfigurationsalternativ överst i dialogrutan Egenskapssidor för projekt:
För Konfiguration väljer du Felsök eller Släpp. (Du kan se de här alternativen med det aktiva prefixet.)
För Plattformen väljer du Aktiv (x64) eller Aktiv (Win32), beroende på ditt val i föregående steg.
Anmärkning
När du skapar egna projekt vill du konfigurera konfigurationerna för felsökning och lansering separat enligt dina specifika scenariokrav. I den här övningen anger du konfigurationerna för att använda en release-build av CPython. Den här konfigurationen inaktiverar vissa felsökningsfunktioner i C++-runtime, inklusive assertioner. Om du använder binärfiler för CPython-felsökning (python_d.exe) krävs olika inställningar.
Ange andra projektegenskaper enligt beskrivningen i följande tabell.
Om du vill ändra ett egenskapsvärde anger du ett värde i egenskapsfältet. För vissa fält kan du välja det aktuella värdet för att expandera en listrutemeny med alternativ eller öppna en dialogruta för att definiera värdet.
När du har uppdaterat värden på en flik väljer du Använd innan du växlar till en annan flik. Den här åtgärden hjälper till att säkerställa att dina ändringar finns kvar.
Flik och avsnitt Fastighet Värde Konfigurationsegenskaper>Allmänt Målnamn Ange namnet på modulen för att referera till den från Python i from...import
-instruktioner, till exempel superfastcode. Du använder samma namn i C++-koden när du definierar modulen för Python. Om du vill använda namnet på projektet som modulnamn lämnar du standardvärdet $<ProjectName>. Förpython_d.exe
lägger du till_d
i slutet av namnet.Konfigurationstyp Dynamiskt bibliotek (.dll) Konfigurationsegenskaper>Avancerad Målfiländelse .pyd (Python-tilläggsmodul ) C/C++>Allmänt Ytterligare inkluderingskataloger Lägg till python-inkluderingsmappen efter behov för installationen (till exempel c:\Python36\include). C/C++>Preprocessor Definitioner för förprocessor Om det finns ändrar du värdet för _DEBUG till NDEBUG så att det matchar nondebug-versionen av CPython. När du använder python_d.exelämnar du det här värdet oförändrat. C/C++>Kodgenerering Körbibliotek Multitrådad DLL (/MD) för att matcha versionen (nondebug) av CPython. När du använder python_d.exelämnar du det här värdet som DLL för flertrådad felsökning (/MDd). Grundläggande körningskontroller Standardinställning Länkare>Allmänt Ytterligare bibliotekskataloger Lägg till mappen Python libs som innehåller .lib-filer efter behov för installationen (till exempel c:\Python36\libs). Se till att peka på mappen libs som innehåller .lib-filer och inte lib-mappen som innehåller .py filer. Viktigt!
Om fliken C/C++ inte visas som ett alternativ för projektegenskaperna innehåller projektet inga kodfiler som Visual Studio identifierar som C/C++-källfiler. Det här villkoret kan inträffa om du skapar en källfil utan filnamnstillägget.c eller .cpp.
Om du av misstag har angett module.coo i stället för module.cpp när du skapade C++-filen skapar Visual Studio filen men anger inte filtypen till C/C+-kompilator. Den här filtypen är nödvändig för att aktivera förekomsten av egenskapsfliken C/C++ i dialogrutan projektegenskaper. Felidentifieringen kvarstår även om du byter namn på kodfilen med ett .cpp filnamnstillägg.
Om du vill ange kodfiltypen korrekt högerklickar du på kodfilen i Solution Explorer och väljer Egenskaper. För Objekttyp väljer du C/C++-kompilator.
När du har uppdaterat alla egenskaper väljer du OK.
Upprepa stegen för den andra byggkonfigurationen.
Testa den aktuella konfigurationen. Upprepa dessa steg för både debug och release builds av båda C++-projekten.
Lägga till kod- och testkonfiguration
Nu är du redo att lägga till kod i dina C++-filer och testa releaseversionen.
För projektet superfastcode C++ öppnar du filen module.cpp i kodredigeraren.
I filen module.cpp klistrar du in följande kod:
#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); }
Spara ändringarna.
Skapa versionskonfigurationen för C++-projektet för att bekräfta att koden är korrekt.
Upprepa stegen för att lägga till kod i C++-filen för superfastcode2-projektet och testa releaseversionen.
Konvertera C++-projekt till Python-tillägg
Om du vill göra C++ DLL till ett tillägg för Python ändrar du först de exporterade metoderna för att interagera med Python-typer. Lägg sedan till en funktion för att exportera modulen, tillsammans med definitioner för modulens metoder.
Följande avsnitt visar hur du skapar tilläggen med hjälp av CPython-tilläggen och PyBind11. Superfasctcode-projektet använder CPython-tilläggen och superfasctcode2-projektet implementerar PyBind11.
Använda CPython-tillägg
Mer information om koden som visas i det här avsnittet finns i Referenshandbok för Python/C API, särskilt sidan Modulobjekt . När du granskar referensinnehållet måste du välja din version av Python i listrutan längst upp till höger.
För projektet superfastcode C++ öppnar du filen module.cpp i kodredigeraren.
Lägg till en instruktion överst i filen module.cpp för att inkludera Python.h-huvudfilen :
#include <Python.h>
tanh_impl
Ersätt metodkoden för att acceptera och returnera Python-typer (det vill: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); }
I slutet av filen lägger du till en struktur för att definiera hur C++
tanh_impl
-funktionen ska presenteras för Python: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 } };
Lägg till en annan struktur för att definiera hur du refererar till modulen i Python-koden, särskilt när du använder -instruktionen
from...import
.Namnet som importeras i den här koden ska matcha värdet i projektegenskaperna underAllmänna>målnamn>.
I följande exempel innebär namnet
"superfastcode"
att du kan använda -instruktionenfrom superfastcode import fast_tanh
i Python eftersomfast_tanh
har definierats isuperfastcode_methods
. Filnamn som är interna för C++-projektet, till exempel module.cpp, är oviktiga.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 };
Lägg till en metod som Python anropar när den läser in modulen. Metodnamnet måste vara
PyInit_<module-name>
, där <modulnamnet> exakt matchar C++-projektets egenskap Konfigurationens Egenskaper>Allmän>Målnamn. Metodnamnet matchar alltså filnamnet för den .pyd-fil som skapats av projektet.PyMODINIT_FUNC PyInit_superfastcode() { return PyModule_Create(&superfastcode_module); }
Skapa C++-projektet och verifiera koden. Om du får fel kan du läsa avsnittet "Felsöka kompileringsfel" .
Använda PyBind11
Om du slutför stegen i föregående avsnitt för superfastcode-projektet kanske du märker att övningen kräver boilerplate-kod för att skapa modulstrukturerna för C++ CPython-tillägg. I den här övningen upptäcker du att PyBind11 förenklar kodningsprocessen. Du använder makron i en C++-huvudfil för att uppnå samma resultat, men med mycket mindre kod. Extra steg krävs dock för att säkerställa att Visual Studio kan hitta PyBind11-biblioteken och inkludera filer. Mer information om koden i det här avsnittet finns i Grunderna för PyBind11.
Installera PyBind11
Det första steget är att installera PyBind11 i projektkonfigurationen. I den här övningen använder du PowerShell-fönstret Developer .
Öppna fönstret Verktyg>Kommandoraden>Developer PowerShell.
I fönstret Developer PowerShell installerar du PyBind11 med hjälp av pip-kommandot
pip install pybind11
ellerpy -m pip install pybind11
.Visual Studio installerar PyBind11 och dess beroende paket.
Lägga till PyBind11-sökvägar i projektet
När PyBind11 har installerats måste du lägga till PyBind11-sökvägarna i egenskapen Ytterligare inkluderade kataloger för projektet.
I Developer PowerShell -fönstret kör du kommandot
python -m pybind11 --includes
ellerpy -m pybind11 --includes
.Den här åtgärden skriver ut en lista över PyBind11-sökvägar som du behöver lägga till i projektegenskaperna.
Markera listan över sökvägar i fönstret och välj Kopiera (dubbel sida) i fönstrets verktygsfält.
Listan över sammanfogade sökvägar läggs till i urklipp.
Högerklicka på projektet superfastcode2 i Solution Explorer och välj Egenskaper.
Längst upp i dialogrutan Egenskapssidor går du till fältet Konfiguration och väljer Släpp. (Du kan se det här alternativet med det aktiva prefixet.)
I dialogrutan går du till fliken C/C++>Allmänt , expanderar den nedrullningsbara menyn för egenskapen Ytterligare inkludera kataloger och väljer Redigera.
I popup-dialogrutan lägger du till listan över kopierade sökvägar:
Upprepa dessa steg för varje sökväg i den sammanfogade listan som kopierats från Developer PowerShell-fönstret:
Välj Ny rad (mapp med plussymbol) i verktygsfältet i popup-dialogrutan.
Visual Studio lägger till en tom rad överst i listan över sökvägar och placerar infogningsmarkören i början.
Klistra in sökvägen PyBind11 i den tomma raden.
Du kan också välja Fler alternativ (...) och använda en dialogruta för popup-utforskaren för att bläddra till sökvägens plats.
Viktigt!
- Om sökvägen innehåller prefixet
-I
tar du bort prefixet från sökvägen. - För att Visual Studio ska kunna identifiera en sökväg måste sökvägen finnas på en separat rad.
När du har lagt till en ny sökväg visar Visual Studio den bekräftade sökvägen i fältet Utvärderat värde .
- Om sökvägen innehåller prefixet
Välj OK för att avsluta popup-dialogrutan.
Längst upp i dialogrutan Egenskapssidor hovrar du över värdet för egenskapen Ytterligare inklusionskataloger och bekräftar att PyBind11-sökvägarna finns.
Välj OK för att tillämpa egenskapsändringarna.
Uppdatera module.cpp-filen
Det sista steget är att lägga till PyBind11-huvudfilen och makrokoden i projektets C++-fil.
För projektet superfastcode2 C++ öppnar du filen module.cpp i kodredigeraren.
Lägg till en instruktion överst i filen module.cpp för att inkludera huvudfilen pybind11.h :
#include <pybind11/pybind11.h>
I slutet av filen module.cpp lägger du till kod för makrot
PYBIND11_MODULE
för att definiera startpunkten för C++-funktionen: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 }
Skapa C++-projektet och verifiera koden. Om du stöter på fel kan du läsa nästa avsnitt Felsöka kompileringsfel.
Felsöka kompileringsfel
I följande avsnitt finns möjliga problem som kan leda till att C++-modulversionen misslyckas.
Fel: Det går inte att hitta huvudfilen
Visual Studio returnerar ett felmeddelande som E1696: Det går inte att öppna källfilen "Python.h" eller C1083: Det går inte att öppna inkluderingsfilen: "Python.h": Ingen sådan fil eller katalog.
Det här felet anger att kompilatorn inte kan hitta en obligatorisk rubrikfil (.h) för projektet.
För superfastcode-projektet kontrollerar du att projektegenskapen C/C++>General>Additional Include Directories innehåller sökvägen till inkluderingsmappen för Python-installationen. Granska stegen i Konfigurera projektegenskaper.
För superfastcode2-projektet kontrollerar du att samma projektegenskap innehåller sökvägen till inkluderingsmappen för pybind11-installationen. Granska stegen Lägg till PyBind-sökvägar till projektet.
Mer information om hur du kommer åt konfigurationsinformationen för Python-installationen finns i Python-dokumentationen.
Fel: Det går inte att hitta Python-bibliotek
Visual Studio returnerar ett fel som anger att kompilatorn inte kan hitta nödvändiga biblioteksfiler (DLL) för projektet.
- För C++-projektet (superfastcode eller superfastcode2) kontrollerar du att egenskapen Linker>General>Additional Library Directories innehåller sökvägen till mappen libs för Python-installationen. Granska stegen i Konfigurera projektegenskaper.
Mer information om hur du kommer åt konfigurationsinformationen för Python-installationen finns i Python-dokumentationen.
Linker-fel relaterade till målarkitektur
Visual Studio rapporterar länkfel relaterade till målarkitekturkonfigurationen för projektet, till exempel x64 eller Win32.
- För C++-projektet (superfastcode eller superfastcode2) ändrar du målkonfigurationen så att den matchar Python-installationen. Om din C++-projektmålkonfiguration till exempel är Win32, men Python-installationen är 64-bitars, ändrar du C++-projektmålkonfigurationen till x64.
Testa koden och jämför resultaten
Nu när du har strukturerat DLL:er som Python-tillägg kan du referera till dem från Python-projektet, importera modulerna och använda deras metoder.
Gör din DLL tillgänglig för Python
Du kan göra din DLL tillgänglig för Python på flera sätt. Här är två alternativ att tänka på:
Om ditt Python-projekt och C++-projekt finns i samma lösning kan du använda följande metod:
Högerklicka på noden Referenser i Python-projektet i Solution Explorer och välj Lägg till referens.
Se till att göra den här åtgärden för Python-projektet och inte för ditt C++-projekt.
I dialogrutan Lägg till referens expanderar du fliken Projekt .
Markera kryssrutorna för både superfastcode - och superfastcode2-projekten och välj OK.
En alternativ metod är att installera C++-tilläggsmodulen i Python-miljön. Den här metoden gör modulen tillgänglig för andra Python-projekt. Mer information finns i projektdokumentationen för setuptools.
Utför följande steg för att installera C++-tilläggsmodulen i Python-miljön:
Högerklicka på ditt C++-projekt i Solution Explorer och välj Lägg till>nytt objekt.
I listan över filmallar väljer du C++-fil (.cpp).
Ange namnet på filen som setup.py och välj sedan Lägg till.
Se till att ange filnamnet med Python-tillägget (.py). Visual Studio identifierar filen som Python-kod trots att C++-filmallen används.
Visual Studio öppnar den nya filen i kodredigeraren.
Klistra in följande kod i den nya filen. Välj den kodversion som motsvarar tilläggsmetoden:
CPython-tillägg (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], )
I C++-projektet skapar du en andra fil med namnet pyproject.toml och klistrar in följande kod:
[build-system] requires = ["setuptools", "wheel", "pybind11"] build-backend = "setuptools.build_meta"
TOML-filen (.toml) använder Formatet Tom's Obvious, Minimal Language för konfigurationsfiler.
Om du vill skapa tillägget högerklickar du på filnamnet pyproject.toml på fliken kodfönster och väljer Kopiera fullständig sökväg.
Du tar bort namnet pyproject.toml från sökvägen innan du använder det.
I Solution Explorer expanderar du noden Python-miljöer för lösningen.
Högerklicka på den aktiva Python-miljön (visas i fetstil) och välj Hantera Python-paket.
Fönstret Python-miljöer öppnas.
Om det nödvändiga paketet redan har installerats visas det i det här fönstret.
- Innan du fortsätter väljer du X bredvid paketnamnet för att avinstallera det.
I sökrutan för fönstret Python-miljöer klistrar du in den kopierade sökvägen och tar bort filnamnet pyproject.toml från slutet av sökvägen.
Välj Retur för att installera modulen från platsen för den kopierade sökvägen.
Tips/Råd
Om installationen misslyckas på grund av ett behörighetsfel lägger du till
--user
argumentet i slutet av kommandot och försöker installera igen.
Anropa DLL:en från Python
När du har gjort DLL-filen tillgänglig för Python, enligt beskrivningen i föregående avsnitt, är du redo att anropa superfastcode.fast_tanh
funktionerna och superfastcode2.fast_tanh2
från Python. Du kan sedan jämföra funktionsprestanda med Python-implementeringen.
Följ de här stegen för att anropa tilläggsmodulens DLL från Python:
Öppna filen .py för Python-projektet i kodredigeraren.
I slutet av filen lägger du till följande kod för att anropa de metoder som exporteras från DLL:erna och visa deras utdata:
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)')
Kör Python-programmet genom att välja Felsöka>Starta utan att felsöka eller använda kortkommandot Ctrl+F5.
Anmärkning
Om kommandot Starta utan felsökning inte är tillgängligt högerklickar du på Python-projektet i Solution Explorer och väljer sedan Ange som startprojekt.
När programmet körs ser du att C++-rutinerna körs ungefär 5 till 20 gånger snabbare än Python-implementeringen.
Här är ett exempel på typiska programutdata:
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
Försök att öka variabeln
COUNT
så att tidsskillnaderna är mer uttalade.En felsökningsversion av C++-modulen körs också långsammare än en versionsversion eftersom felsökningsversionen är mindre optimerad och innehåller olika felkontroller. Prova att växla mellan byggkonfigurationerna för jämförelse, men kom ihåg att uppdatera de egenskaper som du angav tidigare för versionskonfigurationen.
Åtgärda processhastighet och omkostnader
I utdata kanske du märker att PyBind11-tillägget inte är lika snabbt som CPython-tillägget, även om det bör vara snabbare än den rena Python-implementeringen. Den främsta orsaken till skillnaden är att flaggan METH_O används. Den här flaggan stöder inte flera parametrar, parameternamn eller nyckelordsargument. PyBind11 genererar lite mer komplex kod för att tillhandahålla ett mer Python-liknande gränssnitt för anropare. Eftersom testkoden anropar funktionen 500 000 gånger kan resultatet avsevärt öka kostnaderna.
Du kan minska kostnaderna ytterligare genom att flytta loopen for
till den interna Python-koden. Den här metoden innebär att använda iteratorprotokollet (eller PyBind11-typen py::iterable
för funktionsparametern) för att bearbeta varje element. Att ta bort de upprepade övergångarna mellan Python och C++ är ett effektivt sätt att minska den tid det tar att bearbeta sekvensen.
Felsöka importfel
Om du får ett ImportError
meddelande när du försöker importera modulen kan du lösa det på något av följande sätt:
När du skapar via en projektreferens kontrollerar du att dina C++-projektegenskaper matchar Python-miljön som aktiveras för Python-projektet. Bekräfta att samma mappplatser används för filerna Inkludera (.h) och Bibliotek (DLL).
Kontrollera att utdatafilen är korrekt namngiven, till exempel superfastcode.pyd. Ett felaktigt namn eller tillägg förhindrar import av den nödvändiga filen.
Om du installerar modulen med hjälp av setup.py-filen ska du köra
pip
kommandot i Python-miljön som aktiverats för Python-projektet. När du expanderar den aktiva Python-miljön för projektet i Solution Explorer bör du se en post för C++-projektet, till exempel supersnabbkod.
Felsök C++-kod
Visual Studio stöder felsökning av Python- och C++-kod tillsammans. Följande steg visar felsökningsprocessen för projektet superfastcode C++, men processen är densamma för superfastcode2-projektet .
Högerklicka på Python-projektet i Solution Explorer och välj Egenskaper.
I fönstret Egenskaper väljer du fliken Felsök och väljer sedan alternativet Felsök>aktivera intern kodfelsökning .
Tips/Råd
När du aktiverar inbyggd felsökning av kod kan Python-utdatafönstret stängas omedelbart efter att programmet har avslutats utan att pausa eller visa tryck på valfri tangent för att fortsätta frågan. Om du vill framtvinga pausen och uppmaningen när du har aktiverat intern kodfelsökning lägger du till
-i
argumentet i fältet Kör>tolkargument på fliken Felsök . Det här argumentet placerar Python-tolken i interaktivt läge när koden har körts. Programmet väntar på att du ska välja Ctrl+Z+Retur för att stänga fönstret. En alternativ metod är att lägga tillimport os
ochos.system("pause")
instruktioner i slutet av Python-programmet. Den här koden duplicerar den ursprungliga pausprompten.Välj Spara fil> (eller Ctrl+) för att spara egenskapsändringarna.
I Visual Studio-verktygsfältet ställer du in Build-konfigurationen på Felsök.
Eftersom koden vanligtvis tar längre tid att köra i felsökningsprogrammet kanske du vill ändra variabeln
COUNT
i Python-projektet .py filen till ett värde som är ungefär fem gånger mindre än standardvärdet. Du kan till exempel ändra den från 500000 till 100000.I C++-koden anger du en brytpunkt på den första raden i
tanh_impl
metoden.Starta felsökningsprogrammet genom att välja Felsöka>Starta felsökning eller använda kortkommandot F5.
Felsökningsprogrammet stoppas när brytpunktskoden anropas. Om brytpunkten inte nås kontrollerar du att konfigurationen är inställd på Felsöka och att du sparade projektet, vilket inte sker automatiskt när du startar felsökningsprogrammet.
Vid brytpunkten kan du gå igenom C++-koden, undersöka variabler och så vidare. Mer information om dessa funktioner finns i Felsöka Python och C++ tillsammans.
Alternativa sätt
Du kan skapa Python-tillägg på olika sätt, enligt beskrivningen i följande tabell. De första två raderna och CPython
PyBind11
, beskrivs i den här artikeln.
Tillvägagångssätt | Skörd | Representativa användare |
---|---|---|
C/C++-tilläggsmoduler för CPython |
1991 | Standardbibliotek |
PyBind11 (rekommenderas för C++) | 2015 | |
Cython (rekommenderas för C) | 2007 | gevent, kivy |
HPy | 2019 | |
mypyc | 2017 | |
ctypes | 2003 | oscrypto |
cffi | 2013 | kryptografi, pypy |
SLURK | 1996 | crfsuite |
Boost.Python | 2002 | |
cppyy | 2017 |