Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
V tomto článku vytvoříte modul rozšíření C++ pro CPython pro výpočet hyperbolického tangensu a zavoláte ho z kódu Pythonu. Rutina se implementuje jako první v Pythonu, aby ukázala relativní výkon implementace stejné rutiny v jazyce C++.
Moduly kódu napsané v jazyce C++ (nebo C) se běžně používají k rozšíření možností interpreta Pythonu. Existují tři primární typy rozšiřujících modulů:
- Moduly akcelerátoru: Povolte akcelerovaný výkon. Vzhledem k tomu, že Python je interpretovaný jazyk, můžete v jazyce C++ napsat modul akcelerátoru pro zajištění vyššího výkonu.
- Obálkové moduly: Zveřejnění existujících rozhraní C/C++ pro kód Pythonu nebo zveřejnění rozhraní API podobné pythonu, které se dá snadno používat z Pythonu.
-
Moduly přístupu systému nízké úrovně: Vytvořte moduly pro přístup k systému, abyste dosáhli funkcí
CPythonmodulu runtime nižší úrovně, operačního systému nebo základního hardwaru.
Tento článek ukazuje dva způsoby, jak zpřístupnit modul rozšíření jazyka C++pro Python:
- Použijte standardní
CPythonrozšíření, jak je popsáno v dokumentaci k Pythonu. - Použijte PyBind11, který doporučujeme pro C++11 kvůli jednoduchosti. Pokud chcete zajistit kompatibilitu, ujistěte se, že pracujete s jednou z novějších verzí Pythonu.
Dokončená ukázka pro tento názorný postup je k dispozici na GitHubu na python-samples-vs-cpp-extension.
Požadavky
Visual Studio 2017 nebo novější s nainstalovanou úlohou vývoje v Pythonu Tato úloha zahrnuje nativní vývojové nástroje Pythonu, které přidávají úlohy C++ a nástroje pro sestavení nezbytné pro nativní rozšíření.
Další informace o možnostech instalace najdete v tématu Instalace podpory Pythonu pro Visual Studio.
Poznámka:
Při instalaci úlohy datových věd a analytických aplikací se ve výchozím nastavení nainstalují Python a možnost nativních vývojových nástrojů Pythonu .
Pokud instalujete Python samostatně, nezapomeňte v instalátoru Pythonu vybrat možnost Stáhnout symboly ladění v nabídce Upřesnit možnosti. Tato možnost je nezbytná pro ladění ve smíšeném režimu mezi vaším kódem Pythonu a nativním kódem.
Vytvoření aplikace v Pythonu
Pomocí těchto kroků vytvořte aplikaci v Pythonu.
V sadě Visual Studio vytvořte nový projekt Pythonu tak, že vyberete Soubor>nový>projekt.
V dialogovém okně Vytvořit nový projekt vyhledejte Python. Vyberte šablonu aplikace Pythonu a vyberte Další.
Zadejte název aumístění projektu a vyberte Vytvořit.
Visual Studio vytvoří nový projekt. Projekt se otevře v Průzkumníku řešení a soubor projektu (.py) se otevře v editoru kódu.
Do souboru .py vložte následující kód. Pokud chcete vyzkoušet některé funkce pro úpravy Pythonu, zkuste kód zadat ručně.
Tento kód vypočítá hyperbolický tangens bez použití matematické knihovny a později to urychlíte pomocí nativních rozšíření Pythonu.
Návod
Než ho přepíšete v jazyce C++, napíšete svůj kód v čistém Pythonu. Tímto způsobem můžete snadněji zkontrolovat, jestli je váš nativní kód Pythonu správný.
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)')Spusťte program výběrem možnosti ladění>Spustit bez ladění nebo vyberte klávesovou zkratku Ctrl+F5.
Otevře se příkazové okno pro zobrazení výstupu programu.
Ve výstupu si všimněte množství času hlášeného pro proces srovnávacího testu.
V tomto názorném postupu by měl proces srovnávacího testu trvat přibližně 2 sekundy.
Podle potřeby upravte hodnotu
COUNTproměnné v kódu, aby se srovnávací test dokončil přibližně za 2 sekundy na vašem počítači.Spusťte program znovu a potvrďte, že upravená
COUNThodnota vytvoří srovnávací test přibližně za 2 sekundy.
Návod
Při spouštění srovnávacích testů vždy používejte možnost>Spustit bez ladění. Tato metoda pomáhá vyhnout se režii, která může nastat během spuštění kódu v ladicím programu sady Visual Studio.
Vytvoření základních projektů C++
Pomocí těchto kroků vytvořte dva identické projekty C++, superfastcode a superfastcode2. Později v každém projektu použijete jiný přístup k zveřejnění kódu C++ v Pythonu.
V Průzkumníku řešení klikněte pravým tlačítkem na název řešení a vyberte Přidat>nový projekt.
Řešení sady Visual Studio může obsahovat projekty Pythonu i C++, což je jednou z výhod použití sady Visual Studio pro vývoj v Pythonu.
V dialogovém okně Přidat nový projekt nastavte filtr jazyka na C++ a do vyhledávacího pole zadejte prázdné.
V seznamu výsledků šablony projektu vyberte Prázdný projekt a vyberte Další.
V dialogovém okně Konfigurovat nový projekt zadejte název projektu:
- Pro první projekt zadejte název superfastcode.
- Pro druhý projekt zadejte název superfastcode2.
Vyberte Vytvořit.
Nezapomeňte tyto kroky zopakovat a vytvořit dva projekty.
Návod
Alternativní přístup je k dispozici, pokud máte v sadě Visual Studio nainstalované nativní vývojové nástroje Pythonu. Můžete začít se šablonou modulu rozšíření Pythonu , která předem dokončí mnoho kroků popsaných v tomto článku.
Návod v tomto článku vám pomůže začít s prázdným projektem, který vám pomůže krok za krokem sestavit modul rozšíření. Po pochopení procesu můžete pomocí alternativní šablony ušetřit čas při psaní vlastních rozšíření.
Přidání souboru C++ do projektu
V dalším kroku přidejte do každého projektu soubor C++.
V Průzkumníku řešení rozbalte projekt, klikněte pravým tlačítkem myši na uzel Zdrojové soubory a vyberte Přidat>novou položku.
V seznamu šablon souborů vyberte soubor C++ (.cpp).
Jako module.cpp zadejte název souboru a pak vyberte Přidat.
Důležité
Ujistěte se, že název souboru obsahuje příponu .cpp . Visual Studio hledá soubor s příponou .cpp , aby bylo možné zobrazit stránky vlastností projektu C++.
Na panelu nástrojů rozbalte rozevírací nabídku Konfigurace a vyberte typ konfigurace cíle:
- V případě 64bitového modulu runtime Pythonu aktivujte konfiguraci x64 .
- V případě 32bitového modulu runtime Pythonu aktivujte konfiguraci Win32 .
Nezapomeňte tyto kroky zopakovat pro oba projekty.
Konfigurace vlastností projektu
Před přidáním kódu do nových souborů C++ nakonfigurujte vlastnosti pro každý projekt modulu C++ a otestujte konfigurace, abyste měli jistotu, že všechno funguje.
Potřebujete nastavit vlastnosti projektu pro konfigurace sestavení ladění i vydané verze každého modulu.
V Průzkumníku řešení klikněte pravým tlačítkem myši na projekt modulu C++ (superfastcode nebo superfastcode2) a vyberte Vlastnosti.
Nakonfigurujte vlastnosti pro sestavení ladění modulu a pak nakonfigurujte stejné vlastnosti pro sestavení vydané verze :
V horní části dialogového okna Stránky vlastností projektu nakonfigurujte následující možnosti konfigurace souboru:
V části Konfigurace vyberte Ladit nebo Uvolnit. (Tyto možnosti se můžou zobrazit s předponou Aktivní .)
Pro platformu vyberte v závislosti na výběru v předchozím kroku aktivní (x64) nebo Aktivní (Win32).
Poznámka:
Při vytváření vlastních projektů budete chtít nakonfigurovat konfigurace ladění a vydávání samostatně podle konkrétních požadavků na scénář. V tomto cvičení nastavíte konfigurace tak, aby používaly produkční verzi buildu CPythonu. Tato konfigurace zakáže některé funkce ladění modulu runtime Microsoft Visual C++, včetně kontrolních výrazů. Použití ladících binárních souborů CPython (python_d.exe) vyžaduje různá nastavení.
Nastavte další vlastnosti projektu, jak je popsáno v následující tabulce.
Pokud chcete změnit hodnotu vlastnosti, zadejte hodnotu do pole vlastnosti. U některých polí můžete vybrat aktuální hodnotu a rozbalit rozevírací nabídku voleb nebo otevřít dialogové okno, které vám pomůže definovat hodnotu.
Po aktualizaci hodnot na kartě vyberte možnost Použít před přepnutím na jinou kartu. Tímto způsobem zajistíte zachování svých změn.
Karta a sekce Vlastnictví Hodnota Vlastnosti konfigurace>Obecné Název cíle Zadejte název modulu, který se na něj má odkazovat z Pythonu v from...importpříkazech, jako je superfastcode. Stejný název použijete v kódu C++ při definování modulu pro Python. Pokud chcete jako název modulu použít název projektu, ponechte výchozí hodnotu $<ProjectName>. Propython_d.exepřidejte_dna konec názvu.Typ konfigurace Dynamická knihovna (.dll) Vlastnosti konfigurace>Pokročilé Cílová přípona souboru .pyd (modul rozšíření Pythonu) C/C++>Obecné Další zahrnovací adresáře V případě potřeby přidejte složku include Pythonu (například c:\Python36\include). C/C++>Preprocesor Definice preprocesoru Pokud je k dispozici, změňte hodnotu _DEBUG na NDEBUG tak, aby odpovídala nedebugové verzi CPythonu. Pokud použijete python_d.exe, ponechte tuto hodnotu beze změny. C/C++>Generování kódu Knihovna modulu runtime Knihovna DLL s více vlákny (/MD) musí odpovídat vydané verzi CPythonu (bez ladění), aby byla správná. Pokud použijete python_d.exe, ponechte tuto hodnotu jako ladicí knihovnu DLL s více vlákny (/MDd). Základní kontroly modulu runtime výchozí Linker>Obecné Další adresáře knihovny Přidejte složku Python libs obsahující soubory .lib, jak odpovídá vaší instalaci (například c:\Python36\libs). Nezapomeňte odkazovat na složku libs, která obsahuje soubory .lib, a ne na složku Lib, která obsahuje soubory .py. Důležité
Pokud karta C/C++ není zobrazena jako možnost vlastností projektu, pak projekt neobsahuje žádné soubory kódu, které Sada Visual Studio identifikuje jako zdrojové soubory C/C++. K této podmínce může dojít, pokud vytvoříte zdrojový soubor bez přípony souboru .c nebo .cpp .
Pokud jste omylem zadali module.coo místo module.cpp při vytváření souboru C++, Visual Studio soubor vytvoří, ale nenastaví typ souboru na kompilátor C/C+. Tento typ souboru je nezbytný k aktivaci přítomnosti karty vlastností C/C++ v dialogovém okně vlastností projektu. Chybné identifikace zůstane i v případě, že přejmenujete soubor kódu s příponou .cpp .
Chcete-li správně nastavit typ souboru kódu, klikněte v Průzkumníku řešení pravým tlačítkem myši na soubor kódu a vyberte Vlastnosti. Jako typ položky vyberte kompilátor C/C++.
Po aktualizaci všech vlastností vyberte OK.
Opakujte kroky pro jinou konfiguraci sestavení.
Otestujte aktuální konfiguraci. Opakujte následující kroky pro sestavení debug i release obou C++ projektů.
Přidání kódu a testovací konfigurace
Teď jste připraveni přidat kód do souborů C++ a otestovat sestavení vydané verze .
Pro projekt C++ superfastcode otevřete soubor module.cpp v editoru kódu.
Do souboru module.cpp vložte následující kód:
#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); }Uložte změny.
Sestavte konfiguraci vydání pro projekt C++, abyste potvrdili správnost svého kódu.
Opakujte kroky pro přidání kódu do souboru C++ pro projekt superfastcode2 a otestujte sestavení vydané verze .
Převod projektů C++ na rozšíření Pythonu
Chcete-li knihovnu DLL jazyka C++ nastavit jako rozšíření pro Python, nejprve upravíte exportované metody pro interakci s typy Pythonu. Pak přidejte funkci pro export modulu spolu s definicemi metod modulu.
Následující části ukazují, jak vytvořit rozšíření pomocí rozšíření CPython a PyBind11. Projekt superfasctcode používá rozšíření CPython a projekt superfasctcode2 implementuje PyBind11.
Používejte rozšíření CPython
Další informace o kódu zobrazeném v této části najdete v referenční příručce k rozhraní PYTHON/C API, zejména na stránce Objekty modulu . Při kontrole referenčního obsahu nezapomeňte v rozevíracím seznamu v pravém horním rohu vybrat svou verzi Pythonu.
Pro projekt C++ superfastcode otevřete soubor module.cpp v editoru kódu.
Na začátek souboru module.cpp přidejte příkaz, který bude obsahovat hlavičkový soubor Python.h :
#include <Python.h>tanh_implNahraďte kód metody pro přijetí a vrácení typů Pythonu (to znamená :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); }Na konec souboru přidejte strukturu, která definuje, jak prezentovat funkci C++
tanh_impl, do Pythonu: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 } };Přidejte další strukturu, která definuje, jak odkazovat na modul v kódu Pythonu, konkrétně při použití příkazu
from...import.Název importovaný v tomto kódu by se měl shodovat s hodnotou ve vlastnostech projektu v části Vlastnosti konfigurace>Obecné>Název cíle.
V následujícím příkladu
"superfastcode"název znamená, že můžete použítfrom superfastcode import fast_tanhpříkaz v Pythonu, protožefast_tanhje definován v rámcisuperfastcode_methods. Názvy souborů, které jsou interní pro projekt C++, například module.cpp, jsou nekonvenční.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 };Přidejte metodu, kterou Python volá při načítání modulu. Název metody musí být
PyInit_<module-name>, kde <název> modulu přesně odpovídá vlastnosti konfigurace> projektu C++Obecné>cílové název. To znamená, že název metody odpovídá názvu souboru .pyd vytvořeného projektem.PyMODINIT_FUNC PyInit_superfastcode() { return PyModule_Create(&superfastcode_module); }Sestavte projekt C++ a ověřte kód. Pokud narazíte na chyby, přečtěte si část Řešení chyb kompilace .
Použití PyBind11
Pokud dokončíte kroky v předchozí části projektu superfastcode, můžete si všimnout, že cvičení vyžaduje šablonový kód pro vytvoření modulových struktur pro rozšíření CPython v C++. V tomto cvičení zjistíte, že PyBind11 zjednodušuje proces kódování. Makra v souboru hlaviček jazyka C++ slouží k dosažení stejného výsledku, ale s mnohem menším kódem. K zajištění toho, aby Visual Studio mohl vyhledat knihovny PyBind11 a zahrnout soubory, je potřeba provést další kroky. Další informace o kódu v této části najdete v tématu Základy PyBind11.
Instalace PyBind11
Prvním krokem je instalace PyBind11 v konfiguraci projektu. V tomto cvičení použijete okno Developer PowerShellu .
Otevřete okno Nástroje>příkazového řádku>PowerShellu pro vývojáře.
V okně Developer PowerShell nainstalujte PyBind11 pomocí příkazu
pip install pybind11pip nebopy -m pip install pybind11.Visual Studio nainstaluje PyBind11 a závislé balíčky.
Přidat cesty PyBind11 do projektu
Po instalaci PyBind11 je třeba přidat cesty PyBind11 do vlastnosti Další adresáře pro zahrnutí v rámci projektu.
V okně Developer PowerShell spusťte příkaz
python -m pybind11 --includesnebopy -m pybind11 --includes.Tato akce vytiskne seznam cest PyBind11, které potřebujete přidat do vlastností projektu.
Zvýrazněte seznam cest v okně a na panelu nástrojů okna vyberte Kopírovat (dvojitá stránka).
Seznam zřetězených cest se přidá do schránky.
V Průzkumníku řešení klikněte pravým tlačítkem myši na projekt superfastcode2 a vyberte Vlastnosti.
V horní části dialogového okna Stránky vlastností vyberte pro pole Konfigurace možnost Uvolnit. (Tato možnost se může zobrazit s předponou Aktivní .)
V dialogovém okně na kartě C/C++>Obecné rozbalte nabídku vlastnosti Další zahrnuté adresáře a vyberte Upravit.
V místním dialogovém okně přidejte seznam zkopírovaných cest:
Opakujte tento postup pro každou cestu v zřetězeném seznamu zkopírovaném z okna PowerShell Developer:
Vyberte Nový řádek (složka se symbolem plus) na panelu nástrojů v dialogovém okně.
Visual Studio přidá prázdný řádek v horní části seznamu cest a umístí kurzor vložení na začátek.
Vložte cestu PyBind11 do prázdného řádku.
Můžete také vybrat Další možnosti (...) a pomocí vyskakovacího dialogového okna Průzkumníka souborů navigovat na umístění cesty.
Důležité
- Pokud cesta obsahuje předponu
-I, odeberte ji z cesty. - Aby Visual Studio rozpoznal cestu, musí být cesta na samostatném řádku.
Po přidání nové cesty se v prostředí Visual Studio zobrazí potvrzená cesta v poli Vyhodnocená hodnota.
- Pokud cesta obsahuje předponu
Výběrem možnosti OK zavřete automaticky otevírané dialogové okno.
V horní části dialogového okna Stránky vlastností najeďte myší na hodnotu vlastnosti Additional Include Directories a potvrďte, že jsou k dispozici cesty PyBind11.
Chcete-li použít změny vlastností, vyberte OK .
Aktualizace souboru module.cpp
Posledním krokem je přidání souboru hlavičky PyBind11 a kódu makra do souboru C++ projektu.
V případě projektu superfastcode2 C++ otevřete soubor module.cpp v editoru kódu.
Na začátek souboru module.cpp přidejte příkaz, který bude obsahovat hlavičkový soubor pybind11.h :
#include <pybind11/pybind11.h>Na konci souboru module.cpp přidejte kód makra,
PYBIND11_MODULEkterý definuje vstupní bod do funkce C++: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 }Sestavte projekt C++ a ověřte kód. Pokud narazíte na chyby, přečtěte si další část Řešení chyb kompilace.
Řešení chyb kompilace
V následujících částech najdete možné problémy, které můžou způsobit selhání sestavení modulu C++.
Chyba: Nelze najít soubor hlaviček
Visual Studio vrátí chybovou zprávu typu E1696: Nejde otevřít zdrojový soubor Python.h nebo C1083: Nelze otevřít soubor: Python.h: Žádný takový soubor nebo adresář.
Tato chyba značí, že kompilátor nemůže najít požadovaný soubor hlavičky (.h) pro váš projekt.
V případě projektu superfastcode ověřte, že vlastnost projektu C/C++>General Additional>Include Directories obsahuje cestu ke složce include pro instalaci Pythonu. Projděte si kroky v části Konfigurace vlastností projektu.
V případě projektu superfastcode2 ověřte, že stejná vlastnost projektu obsahuje cestu ke složce include pro vaši instalaci PyBind11. Projděte si kroky přidání cest PyBind do projektu.
Další informace o přístupu k informacím o konfiguraci instalace Pythonu najdete v dokumentaci k Pythonu.
Chyba: Nepodařilo se najít knihovny Pythonu
Visual Studio vrátí chybu, která značí, že kompilátor nemůže najít požadované soubory knihovny (DLL) pro váš projekt.
- Pro projekt C++ (superfastcode nebo superfastcode2) ověřte, zda vlastnost Linker>General>Additional Library Directories obsahuje cestu ke složce libs pro instalaci Pythonu. Projděte si kroky v části Konfigurace vlastností projektu.
Další informace o přístupu k informacím o konfiguraci instalace Pythonu najdete v dokumentaci k Pythonu.
Chyby linkeru související s cílovou architekturou
Visual Studio hlásí chyby linkeru související s konfigurací cílové architektury pro váš projekt, například x64 nebo Win32.
- U projektu C++ (superfastcode nebo superfastcode2) změňte cílovou konfiguraci tak, aby odpovídala instalaci Pythonu. Pokud je například konfigurace cíle projektu C++ Win32, ale instalace Pythonu je 64bitová, změňte konfiguraci cíle projektu C++ na x64.
Otestování kódu a porovnání výsledků
Teď, když máte knihovny DLL strukturované jako rozšíření Pythonu, můžete na ně odkazovat z projektu Pythonu, importovat moduly a používat jejich metody.
Zpřístupnění knihovny DLL pythonu
Knihovnu DLL můžete zpřístupnit pro Python několika způsoby. Tady jsou dvě možnosti, které je potřeba vzít v úvahu:
Pokud se projekt Pythonu a projekt C++ nacházejí ve stejném řešení, můžete použít následující přístup:
V Průzkumníku řešení klikněte pravým tlačítkem myši na uzel Reference v projektu Pythonu a vyberte Přidat odkaz.
Nezapomeňte provést tuto akci pro projekt Pythonu, a ne pro projekt C++.
V dialogovém okně Přidat odkaz rozbalte kartu Projekty .
Zaškrtněte políčka u projektů superfastcode i superfastcode2 a vyberte OK.
Alternativním přístupem je instalace modulu rozšíření C++ ve vašem prostředí Pythonu. Tato metoda zpřístupňuje modul ostatním projektům Pythonu. Další informace najdete v dokumentaci k projektu setuptools.
Provedením následujících kroků nainstalujte modul rozšíření C++ve vašem prostředí Pythonu:
V Průzkumníku řešení klikněte pravým tlačítkem na projekt C++ a vyberte Přidat>novou položku.
V seznamu šablon souborů vyberte soubor C++ (.cpp).
Jako setup.py zadejte název souboru a pak vyberte Přidat.
Nezapomeňte zadat název souboru s příponou Python (.py). Visual Studio rozpozná soubor jako kód Pythonu navzdory použití šablony souboru C++.
Visual Studio otevře nový soubor v editoru kódu.
Do nového souboru vložte následující kód. Zvolte verzi kódu, která odpovídá vaší metodě rozšíření:
Rozšíření CPython (projekt superfastcode ):
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 (projekt superfastcode2 ):
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], )
V projektu C++ vytvořte druhý soubor s názvem pyproject.toml a vložte následující kód:
[build-system] requires = ["setuptools", "wheel", "pybind11"] build-backend = "setuptools.build_meta"Soubor TOML (.toml) používá pro konfigurační soubory formát Tom's Obvious, Minimal Language.
Chcete-li vytvořit rozšíření, klikněte pravým tlačítkem myši na název souboru pyproject.toml na kartě okna kódu a vyberte Kopírovat úplnou cestu.
Před použitím cesty odstraníte název pyproject.toml .
V Průzkumníku řešení rozbalte uzel Prostředí Pythonu pro řešení.
Klikněte pravým tlačítkem na aktivní prostředí Pythonu (zobrazené tučně) a vyberte Spravovat balíčky Pythonu.
Otevře se podokno Prostředí Pythonu .
Pokud už je potřebný balíček nainstalovaný, zobrazí se v tomto podokně.
- Než budete pokračovat, vyberte X vedle názvu balíčku a odinstalujte ho.
Do vyhledávacího pole pro podokno Prostředí Pythonu vložte zkopírovanou cestu a odstraňte název souboru pyproject.toml z konce cesty.
Výběrem klávesy Enter nainstalujte modul z umístění zkopírované cesty.
Návod
Pokud instalace selže kvůli chybě oprávnění, přidejte
--userargument na konec příkazu a zkuste instalaci zopakovat.
Volání knihovny DLL z Pythonu
Po zpřístupnění knihovny DLL pro Python, jak je popsáno v předchozí části, jste připraveni volat funkce superfastcode.fast_tanh a superfastcode2.fast_tanh2 z prostředí Pythonu. Pak můžete porovnat výkon funkce s implementací Pythonu.
Pokud chcete volat knihovnu DLL modulu rozšíření z Pythonu, postupujte takto:
Otevřete soubor .py projektu Pythonu v editoru kódu.
Na konec souboru přidejte následující kód pro volání metod exportovaných z knihoven DLL a zobrazení jejich výstupu:
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)')Spusťte program Python výběrem možnosti Spustit>bez ladění nebo použitím klávesové zkratky Ctrl+F5.
Poznámka:
Pokud příkaz Spustit bez ladění není k dispozici, klikněte v Průzkumníku řešení pravým tlačítkem myši na projekt Pythonu a pak vyberte Nastavit jako spouštěný projekt.
Při spuštění programu si všimněte, že rutiny jazyka C++ běží přibližně 5 až 20krát rychleji než implementace Pythonu.
Tady je příklad typického výstupu programu:
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 secondsZkuste proměnnou
COUNTzvětšit, aby byly časové rozdíly výraznější.Sestavení ladění modulu C++ běží také pomaleji než produkční sestavení, protože sestavení ladění je méně optimalizované a obsahuje různé kontroly chyb. Zkuste přepnout mezi konfiguracemi sestavení pro porovnání, ale nezapomeňte aktualizovat vlastnosti, které jste nastavili dříve pro konfiguraci vydané verze.
Řešit rychlost a zatížení procesů
Ve výstupu si můžete všimnout, že rozšíření PyBind11 není tak rychlé jako rozšíření CPython, i když by mělo být rychlejší než čistá implementace Pythonu. Hlavním důvodem rozdílu je použití příznaku METH_O. Tento příznak nepodporuje více parametrů, názvů parametrů ani argumentů klíčových slov. PyBind11 vygeneruje trochu složitější kód, který volajícím poskytne více rozhraní podobné Pythonu. Vzhledem k tomu, že testovací kód volá funkci 500 000krát, výsledky mohou výrazně zvýšit režii.
Režijní náklady můžete dále snížit přesunutím for smyčky do nativního kódu Pythonu. Tento přístup zahrnuje použití protokolu iterátoru (nebo typu PyBind11 py::iterable pro parametr funkce) ke zpracování jednotlivých prvků. Odebrání opakovaných přechodů mezi Pythonem a C++ je efektivní způsob, jak zkrátit dobu potřebnou ke zpracování sekvence.
Řešení chyb importu
Pokud se vám při pokusu ImportError o import modulu zobrazí zpráva, můžete ji vyřešit jedním z následujících způsobů:
Při sestavování prostřednictvím odkazu na projekt se ujistěte, že vlastnosti projektu C++ odpovídají prostředí Pythonu aktivovanému pro váš projekt Pythonu. Ověřte, že se pro soubory Include (.h) a Library (DLL) používají stejná umístění složek.
Ujistěte se, že je výstupní soubor správně pojmenovaný, například superfastcode.pyd. Nesprávný název nebo přípona brání importu potřebného souboru.
Pokud modul nainstalujete pomocí souboru setup.py , nezapomeňte spustit
pippříkaz v prostředí Python aktivovaném pro váš projekt Pythonu. Když rozbalíte aktivní prostředí Pythonu pro váš projekt v Průzkumníku řešení, měli byste vidět položku pro projekt C++, jako je superfastcode.
Ladění kódu C++
Visual Studio podporuje společně ladění kódu Pythonu a C++. Následující kroky ukazují proces ladění pro projekt superfastcode C++, ale proces je stejný pro projekt superfastcode2.
V Průzkumníku řešení klikněte pravým tlačítkem na projekt Pythonu a vyberte Vlastnosti.
V podokně Vlastnosti vyberte kartu Ladění a pak vyberte možnost Ladění>Povolit nativní ladění kódu .
Návod
Když povolíte ladění nativního kódu, okno výstupu Pythonu se může zavřít hned po dokončení programu bez pozastavení a zobrazení výzvy stisknutím libovolné klávesy . Chcete-li vynutit pozastavení a výzvu po povolení ladění nativního kódu, přidejte
-iargument do pole Spustit>argumenty interpretu na kartě Ladění . Tento argument umístí interpret Pythonu do interaktivního režimu po spuštění kódu. Program čeká, až vyberete Ctrl+Z+Enter, abyste zavřeli okno. Alternativním přístupem je přidat příkazyimport osaos.system("pause")na konec vašeho programu v Pythonu. Tento kód duplikuje původní výzvu k pozastavení.Výběrem možnosti Uložit> (nebo Ctrl+S) uložte změny vlastnosti.
Na panelu nástrojů sady Visual Studio nastavte konfiguraci sestavení na Ladění.
Vzhledem k tomu, že spuštění kódu v ladicím programu obvykle trvá déle, můžete změnit
COUNTproměnnou v projektu Pythonu .py souboru na hodnotu, která je asi pětkrát menší než výchozí hodnota. Změňte ho například z 5 00000 na1 00000.V kódu C++ nastavte zarážku na prvním řádku
tanh_implmetody.Spusťte ladicí program výběrem položky Ladění>Spustit ladění nebo použijte klávesovou zkratku F5.
Ladicí program se zastaví při zavolání kódu bodu přerušení. Pokud není zarážka dosažena, zkontrolujte, jestli je konfigurace nastavená na Ladění a že jste projekt uložili, což se nestane automaticky při spuštění debuggeru.
Na bodu přerušení můžete procházet kód C++, prohlížet proměnné atd. Další informace o těchto funkcích najdete v tématu Ladění Pythonu a jazyka C++ společně.
Alternativní přístupy
Rozšíření Pythonu můžete vytvářet různými způsoby, jak je popsáno v následující tabulce. První dva řádky CPython a PyBind11, jsou popsány v tomto článku.
| Přístup | Starý | Reprezentativní uživatelé |
|---|---|---|
Moduly rozšíření C/C++ pro CPython |
1991 | Standardní knihovna |
| PyBind11 (doporučeno pro C++) | 2015 | |
| Cython (doporučeno pro C) | 2007 | gevent, kivy |
| HPy | 2019 | |
| mypyc | 2017 | |
| ctypes | 2003 | oscrypto |
| cffi | 2013 | kryptografie, pypy |
| DOUŠEK | 1996 | crfsuite |
| Boost.Python | 2002 | |
| cppyy | 2017 |