Vytvoření rozšíření jazyka C++ pro Python v sadě Visual Studio
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í
CPython
modulu 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í
CPython
rozšíř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í sady funkcí a sad nástrojů C++, které jsou 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 instalačním programu Pythonu vybrat možnost Stáhnout symboly ladění v části Upřesnit možnosti . Tato možnost je nutná pro použití ladění ve smíšeném režimu mezi 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 a umístění projektu a vyberte Vytvořit.
Visual Studio vytvoří nový projekt. Projekt se otevře v Průzkumník ř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.
Tip
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 tak, že vyberete Spustit ladění>bez ladění nebo vyberete 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
COUNT
promě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á
COUNT
hodnota vytvoří srovnávací test přibližně za 2 sekundy.
Tip
Při spouštění srovnávacích testů vždy používejte možnost Spustit ladění>bez možnosti Ladění. Tato metoda pomáhá vyhnout se režii, která se může zobrazit při 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ík ř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.
Tip
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ík ř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ík ř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 pomocí Aktivní předpona.)
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 build verze CPythonu. Tato konfigurace zakáže některé funkce ladění modulu runtime C++, včetně kontrolních výrazů. Použití binárních souborů ladění 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 Před přepnutím na jinou kartu možnost Použít . Tato akce pomáhá zajistit, aby vaše změny zůstaly.
Tab a section Vlastnost Hodnota Obecné vlastnosti>konfigurace Název cíle Zadejte název modulu, který se na něj má odkazovat z Pythonu v from...import
pří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>. Pokudpython_d.exe
chcete, přidejte_d
na konec názvu.Typ konfigurace Dynamická knihovna (.dll) Upřesnit vlastnosti>konfigurace Cílová přípona souboru .pyd (modul rozšíření Pythonu) Obecné C/C++> Další adresáře zahrnutí Podle potřeby přidejte složku pro zahrnutí Pythonu (například c:\Python36\include). Preprocesor C/C++> 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. Generování kódu C/C++> Knihovna modulu runtime Knihovna DLL s více vlákny (/MD) tak , aby odpovídala verzi CPythonu (nedebug). Pokud použijete python_d.exe, ponechte tuto hodnotu jako knihovnu DLL s více vlákny (/MDd). Základní kontroly modulu runtime Výchozí Obecné linkery> Další adresáře knihovny Přidejte složku knihovny Pythonu, která obsahuje soubory .lib, podle potřeby pro instalaci (například c:\Python36\libs). Nezapomeňte odkazovat na složku knihovny , která obsahuje soubory .lib , a ne složku Lib , která obsahuje .py soubory. 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 vytvoří soubor, 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ík ř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í ladění i vydané verze obou projektů C++.
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 provedené změny.
Sestavte konfiguraci verze pro projekt C++, abyste potvrdili správnost 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žití 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_impl
Nahraď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 Obecné>název cíle vlastností>konfigurace.
V následujícím příkladu
"superfastcode"
název znamená, že můžete použítfrom superfastcode import fast_tanh
příkaz v Pythonu, protožefast_tanh
je 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 často používaný kód k vytvoření struktur modulů pro rozšíření C++ CPython. 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 PowerShellu pro vývojáře příkazového řádku>Nástroje.>
V okně Developer PowerShell nainstalujte PyBind11 pomocí příkazu
pip install pybind11
pip nebopy -m pip install pybind11
.Visual Studio nainstaluje PyBind11 a závislé balíčky.
Přidání cest PyBind11 do projektu
Po instalaci PyBind11 musíte přidat cesty PyBind11 do vlastnosti Další adresáře include pro projekt.
V Prostředí Developer PowerShell v okně spusťte příkaz
python -m pybind11 --includes
nebopy -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ík ř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 pomocí Aktivní předpona.)
V dialogovém okně na kartě C/C++>Obecné rozbalte rozevírací nabídku pro vlastnost Další adresáře include 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ého seznamu zkopírovaného z okna Developer PowerShellu:
Na panelu nástrojů automaticky otevírané dialogové okno vyberte Nový řádek (složka se symbolem plus).
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í automaticky otevírané dialogové okno Průzkumníka souborů přejít 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 sadě 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_MODULE
který definuje vstupní bod 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 vyhoví tomuto požadavku 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 ad PyBind cest k 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 vyhoví, 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 pythonu 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ík ř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ík ř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ík ř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.
Tip
Pokud instalace selže kvůli chybě oprávnění, přidejte
--user
argument 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 superfastcode.fast_tanh
funkce a superfastcode2.fast_tanh2
funkce z 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 tak, že vyberete Spustit ladění>bez ladění nebo použijete klávesovou zkratku Ctrl+F5.
Poznámka:
Pokud příkaz Spustit bez ladění není k dispozici, klikněte v Průzkumník ř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 seconds
Zkuste proměnnou
COUNT
zvětšit, aby byly časové rozdíly výraznější.Sestavení ladění modulu C++ také běží pomaleji než sestavení vydané verze , 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.
Adresovat rychlost a režijní náklady na procesy
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
pip
příkaz v prostředí Python aktivovaném pro váš projekt Pythonu. Když v Průzkumník řešení rozbalíte aktivní prostředí Pythonu, měli byste vidět položku pro projekt C++, například 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ík ř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.
Tip
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
-i
argument 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 a zavřete okno. Alternativním přístupem je přidáníimport os
příkazůos.system("pause")
na konec programu v Pythonu. Tento kód duplikuje původní výzvu k pozastavení.Výběrem možnosti Uložit soubor>(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
COUNT
změnit promě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 na 1 00000.V kódu C++ nastavte zarážku na prvním řádku
tanh_impl
metody.Ladicí program spusťte tak>, že vyberete Ladění spustit nebo použijete klávesovou zkratku F5.
Ladicí program se zastaví při zavolání kódu zarážky. Pokud se zarážka nenarazí, zkontrolujte, jestli je konfigurace nastavená na Ladění a že jste projekt uložili, což se nestane automaticky při spuštění ladicího programu.
Na zarážce můžete procházet kód C++, zkoumat 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 |
SWIG | 1996 | crfsuite |
Boost.Python | 2002 | |
cppyy | 2017 |