Společné ladění Pythonu a C++ v sadě Visual Studio
Většina běžných ladicích programů Pythonu podporuje pouze ladění kódu Pythonu, ale pro vývojáře je běžné používat Python s jazykem C nebo C++. Některé scénáře, které používají smíšený kód, jsou aplikace, které vyžadují vysoký výkon nebo schopnost přímo vyvolat rozhraní API platformy, jsou často kódovány v Pythonu a C nebo C++.
Visual Studio poskytuje integrované souběžné ladění ve smíšeném režimu pro python a nativní kód jazyka C/C++. Podpora je dostupná, když v instalačním programu sady Visual Studio vyberete možnost nativních vývojových nástrojů Pythonu pro úlohu Vývoj pro Python:
V tomto článku se dozvíte, jak pracovat s následujícími funkcemi ladění ve smíšeném režimu:
- Kombinované zásobníky volání
- Krok mezi Pythonem a nativním kódem
- Zarážky v obou typech kódu
- Zobrazení reprezentací objektů v nativních rámcích a naopak
- Ladění v kontextu projektu Pythonu nebo projektu C++
Požadavky
Visual Studio 2017 a novější Ladění ve smíšeném režimu není dostupné v nástrojích Python Tools for Visual Studio 1.x v sadě Visual Studio 2015 a starších verzích.
Visual Studio nainstalované s podporou úloh Pythonu Další informace najdete v tématu Instalace podpory Pythonu v sadě Visual Studio.
Povolení ladění ve smíšeném režimu v projektu Pythonu
Následující kroky popisují, jak povolit ladění ve smíšeném režimu v projektu Pythonu:
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:
Tato možnost umožňuje smíšený režim pro všechny relace ladění.
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.Výběrem možnosti Uložit soubor>(nebo Ctrl+S) uložte změny vlastnosti.
Pokud chcete k existujícímu procesu připojit ladicí program ve smíšeném režimu, vyberte Připojit k procesu ladění>. Otevře se dialogové okno.
V dialogovém okně Připojit k procesu vyberte v seznamu příslušný proces.
Pro pole Připojit k pomocí možnosti Vybrat otevřete dialogové okno Vybrat typ kódu.
V dialogovém okně Vybrat typ kódu zvolte možnost Ladit tyto typy kódu.
V seznamu zaškrtněte políčko Python (nativní) a vyberte OK:
Chcete-li spustit ladicí program, vyberte Připojit .
Nastavení typu kódu je trvalé. Pokud chcete později zakázat ladění ve smíšeném režimu a připojit se k jinému procesu, zrušte zaškrtnutí políčka Typ kódu Pythonu (nativní) a zaškrtněte políčko Typ nativního kódu.
Kromě možnosti Native (Nativní) můžete vybrat i jiné typy kódu. Pokud například spravovaná aplikace hostuje CPython, který zase používá nativní rozšiřující moduly a chcete ladit všechny tři projekty kódu, zaškrtněte políčka Python, Native a Managed . Tento přístup poskytuje jednotné prostředí ladění, včetně kombinovaných zásobníků volání a krokování mezi všemi třemi moduly runtime.
Práce s virtuálními prostředími
Při použití této metody ladění ve smíšeném režimu pro virtuální prostředí (venvs), Python pro Windows používá python.exe
soubor zástupných procedur pro venvs, které Sada Visual Studio najde a načte jako podproces.
V případě Pythonu 3.8 a novějšího nepodporuje smíšený režim ladění s více procesy. Při spuštění ladicí relace se dílčí proces zástupných procedur ladí místo aplikace. V případě scénářů připojení je alternativním řešením připojit se ke správnému
python.exe
souboru. Při spuštění aplikace s laděním (například pomocí klávesové zkratky F5 ) můžete vytvořit venv pomocí příkazuC:\Python310-64\python.exe -m venv venv --symlinks
. V příkazu vložte upřednostňovanou verzi Pythonu. Ve výchozím nastavení můžou symlinky ve Windows vytvářet jenom správci.U verzí Pythonu starších než 3.8 by ladění smíšeného režimu mělo fungovat podle očekávání s venvs.
Spuštění v globálním prostředí nezpůsobuje tyto problémy pro žádnou verzi Pythonu.
Instalace symbolů Pythonu
Při prvním spuštění ladění ve smíšeném režimu se může zobrazit dialogové okno Povinné symboly Pythonu. Symboly je potřeba nainstalovat jenom jednou pro libovolné prostředí Pythonu. Symboly se automaticky zahrnou, pokud nainstalujete podporu Pythonu prostřednictvím Instalační program pro Visual Studio (Visual Studio 2017 a novější). Další informace najdete v tématu Instalace symbolů ladění pro interprety Pythonu v sadě Visual Studio.
Přístup ke zdrojovému kódu Pythonu
Zdrojový kód pro samotný standardní Python můžete zpřístupnit při ladění.
Přejděte na
https://www.python.org/downloads/source/
.Stáhněte si archiv zdrojového kódu Pythonu odpovídající vaší verzi a extrahujte kód do složky.
Když visual Studio vyzve k zadání umístění zdrojového kódu Pythonu, přejděte na konkrétní soubory ve složce pro extrakci.
Povolení ladění ve smíšeném režimu v projektu C/C++
Visual Studio 2017 verze 15.5 a novější podporuje ladění ve smíšeném režimu z projektu C/C++. Příkladem tohoto použití je, když chcete vložit Python do jiné aplikace, jak je popsáno v python.org.
Následující kroky popisují, jak povolit ladění ve smíšeném režimu pro projekt C/C++:
V Průzkumník řešení klikněte pravým tlačítkem myši na projekt C/C++ a vyberte Vlastnosti.
V podokně Stránky vlastností vyberte kartu Ladění vlastností>konfigurace.
Rozbalte rozevírací nabídku pro ladicí program, aby se spustila možnost, a vyberte Python nebo Nativní ladění.
Poznámka:
Pokud možnost Ladění v Pythonu nebo nativním ladění nevidíte, musíte nejprve nainstalovat nativní vývojové nástroje Pythonu pomocí Instalační program pro Visual Studio. Možnost nativního ladění je k dispozici v rámci vývojové úlohy Pythonu. Další informace najdete v tématu Instalace podpory Pythonu v sadě Visual Studio.
Kliknutím na TLAČÍTKO OK uložte změny.
Ladění spouštěče programů
Při použití této metody nelze ladit py.exe
spouštěč programů, protože vytváří podřízený python.exe
podproces. Ladicí program se nepřipojte k podprocesu. V tomto scénáři je alternativním řešením spustit python.exe
program přímo s argumenty následujícím způsobem:
V podokně Stránky vlastností projektu C/C++ přejděte na kartu Ladění vlastností> konfigurace.
Pro možnost Příkaz zadejte úplnou cestu k
python.exe
souboru programu.Do pole Argumenty příkazu zadejte požadované argumenty.
Připojení ladicího programu ve smíšeném režimu
Pro Visual Studio 2017 verze 15.4 a starší je přímé ladění smíšeného režimu povoleno pouze při spuštění projektu Pythonu v sadě Visual Studio. Podpora je omezená, protože projekty C/C++ používají pouze nativní ladicí program.
V tomto scénáři je alternativním řešením připojit ladicí program samostatně:
Spusťte projekt C++ bez ladění tak>, že vyberete Spustit ladění bez ladění nebo použijete klávesovou zkratku Ctrl+F5.
Pokud chcete k existujícímu procesu připojit ladicí program ve smíšeném režimu, vyberte Připojit k procesu ladění>. Otevře se dialogové okno.
V dialogovém okně Připojit k procesu vyberte v seznamu příslušný proces.
Pro pole Připojit k pomocí možnosti Vybrat otevřete dialogové okno Vybrat typ kódu.
V dialogovém okně Vybrat typ kódu zvolte možnost Ladit tyto typy kódu.
V seznamu zaškrtněte políčko Python a vyberte OK.
Chcete-li spustit ladicí program, vyberte Připojit .
Tip
Do aplikace C++ můžete přidat pozastavení nebo zpoždění, abyste se ujistili, že před připojením ladicího programu nevolá kód Pythonu, který chcete ladit.
Prozkoumání funkcí specifických pro smíšený režim
Visual Studio nabízí několik funkcí ladění ve smíšeném režimu, které usnadňují ladění aplikace:
- Kombinovaný zásobník volání
- Krok mezi Pythonem a nativním kódem
- Zobrazení hodnot PyObject v nativním kódu
- Zobrazení nativních hodnot v kódu Pythonu
Použití kombinovaného zásobníku volání
V okně Zásobník volání se zobrazují nativní rámce zásobníku Pythonu prokládání s přechody označenými mezi těmito dvěma:
Pokud chcete, aby se přechody zobrazovaly jako [externí kód] bez zadání směru přechodu, nastavte možnost Možnosti>>nástroje>Ladění obecné>povolit pouze můj kód.
Pokud chcete aktivovat libovolný rámec volání, poklikejte na rámec. Tato akce také otevře odpovídající zdrojový kód, pokud je to možné. Pokud zdrojový kód není dostupný, je rámec stále aktivní a je možné zkontrolovat místní proměnné.
Krok mezi Pythonem a nativním kódem
Visual Studio poskytuje příkazy Step Into (F11) nebo Step Out (Shift+F11), které umožňují ladicím programu smíšeného režimu správně zpracovávat změny mezi typy kódu.
Když Python volá metodu typu implementovaného v jazyce C, krokování volání této metody se zastaví na začátku nativní funkce, která implementuje metodu.
K tomuto chování dochází, když nativní kód volá funkci rozhraní PYTHON API, která má za následek vyvolání kódu Pythonu. Krokování volání
PyObject_CallObject
hodnoty funkce původně definované v Pythonu se zastaví na začátku funkce Pythonu.Krokování z Pythonu na nativní je také podporováno pro nativní funkce vyvolané z Pythonu prostřednictvím typů ctype.
Použití zobrazení hodnot PyObject v nativním kódu
Pokud je aktivní nativní rámec (C nebo C++), místní proměnné se zobrazí v okně Locals ladicího programu. V nativních rozšiřujících modulech Pythonu je mnoho z těchto proměnných typu PyObject
(což je typedef pro _object
) nebo několik dalších základních typů Pythonu. V ladění ve smíšeném režimu tyto hodnoty představují další podřízený uzel označený jako [zobrazení Pythonu].
Pokud chcete zobrazit reprezentaci Pythonu proměnné, rozbalte uzel. Zobrazení proměnných je stejné jako v případě, že se v rámci Pythonu nachází místní proměnná odkazující na stejný objekt. Podřízené položky tohoto uzlu se dají upravovat.
Pokud chcete tuto funkci zakázat, klikněte pravým tlačítkem na libovolné místo v okně Místní hodnoty a přepněte možnost nabídky Zobrazit uzly zobrazení Pythonu>:
Typy jazyka C, které zobrazují uzly zobrazení Pythonu
Následující typy jazyka C zobrazují uzly [zobrazení Pythonu], pokud jsou povolené:
PyObject
PyVarObject
PyTypeObject
PyByteArrayObject
PyBytesObject
PyTupleObject
PyListObject
PyDictObject
PySetObject
PyIntObject
PyLongObject
PyFloatObject
PyStringObject
PyUnicodeObject
[Zobrazení Pythonu] automaticky se nezobrazuje u typů, které sami vytvoříte. Když vytvoříte rozšíření pro Python 3.x, obvykle to není problém. Každý objekt má ob_base
nakonec pole jednoho z uvedených typů jazyka C, což způsobí, že se zobrazí [zobrazení Pythonu].
Zobrazení nativních hodnot v kódu Pythonu
Pokud je aktivní rámeček Pythonu, můžete povolit zobrazení [C++] pro nativní hodnoty v okně Místní hodnoty. Tato funkce není ve výchozím nastavení povolená.
Pokud chcete tuto funkci povolit, klikněte pravým tlačítkem v okně Místní hodnoty a nastavte možnost nabídky Zobrazit uzly zobrazení jazyka Python>C++.
Uzel [zobrazení C++] poskytuje reprezentaci základní struktury C/C++ pro hodnotu, která je identická s tím, co vidíte v nativním rámci. Zobrazuje instanci
_longobject
(pro kterouPyLongObject
je typedef) pro dlouhé celé číslo Pythonu a snaží se odvodit typy pro nativní třídy, které sami vytvoříte. Podřízené položky tohoto uzlu se dají upravovat.
Pokud je podřízené pole objektu typu PyObject
nebo jiného podporovaného typu, má uzel reprezentace [zobrazení Pythonu] (pokud jsou tyto reprezentace povolené). Díky tomuto chování můžete procházet grafy objektů, ve kterých nejsou odkazy přímo vystavené Pythonu.
Na rozdíl od uzlů [zobrazení Pythonu] využívajících metadata objektu Pythonu k určení typu objektu neexistuje podobný mechanismus pro [zobrazení C++]. Obecně řečeno, vzhledem k hodnotě Pythonu (tj PyObject
. odkazu) není možné spolehlivě určit, která struktura C/C++ ji podporuje. Ladicí program smíšeného režimu se pokusí typ odhadnout tak, že se podívá na různá pole typu objektu (například PyTypeObject
odkazovaná podle jeho ob_type
pole), která mají typy ukazatelů funkce. Pokud některý z těchto ukazatelů funkce odkazuje na funkci, která se dá přeložit, a tato funkce má self
parametr s typem konkrétnějším než PyObject*
, předpokládá se, že se jedná o záložní typ.
Podívejte se na následující příklad, kde ob_type->tp_init
hodnota daného objektu odkazuje na následující funkci:
static int FobObject_init(FobObject* self, PyObject* args, PyObject* kwds) {
return 0;
}
V tomto případě ladicí program může správně odvodit, že typ jazyka C objektu je FobObject
. Pokud ladicí program nedokáže určit přesnější typ z tp_init
, přesune se do jiných polí. Pokud nelze odvodit typ z některého z těchto polí, uzel [zobrazení C++] zobrazí objekt jako PyObject
instanci.
Pokud chcete vždy získat užitečnou reprezentaci pro vlastní vytvořené typy, je nejlepší při registraci typu zaregistrovat aspoň jednu speciální funkci a použít parametr silného typu self
. Většina typů tento požadavek splňuje přirozeně. Pro jiné typy je tp_init
kontrola obvykle nejpohodlnější vstup pro tento účel. Fiktivní implementace tp_init
pro typ, který je k dispozici pouze pro povolení odvození typu ladicího programu, může okamžitě vrátit nula, stejně jako v předchozím příkladu.
Kontrola rozdílů oproti standardnímu ladění Pythonu
Ladicí program smíšeného režimu se liší od standardního ladicího programu Pythonu. Představuje některé další funkce, ale chybí některé funkce související s Pythonem, a to následujícím způsobem:
- Mezi nepodporované funkce patří podmíněné zarážky, okno Debug Interactive a vzdálené ladění napříč platformami.
- Okno Okamžité je k dispozici, ale s omezenou podmnožinou jeho funkcí, včetně všech omezení uvedených v této části.
- Podporované verze Pythonu zahrnují pouze CPython 2.7 a 3.3+.
- Pokud chcete použít Python se sadou Visual Studio Shell (například pokud ho nainstalujete pomocí integrovaného instalačního programu), Visual Studio nemůže otevřít projekty C++. V důsledku toho je prostředí pro úpravy pro soubory C++ pouze v základním textovém editoru. Ladění C/C++ a ladění ve smíšeném režimu jsou však plně podporovány v prostředí se zdrojovým kódem, krokováním do nativního kódu a vyhodnocením výrazu C++ v oknech ladicího programu.
- Při zobrazení objektů Pythonu v oknech nástrojů Locals a Watch debugger zobrazí ladicí program smíšeného režimu pouze strukturu objektů. Nevyhodnocuje automaticky vlastnosti ani nezobrazuje vypočítané atributy. U kolekcí zobrazuje pouze prvky pro předdefinované typy kolekcí (
tuple
,list
,dict
,set
). Vlastní typy kolekcí nejsou vizualizovány jako kolekce, pokud nejsou zděděny z některého předdefinovaného typu kolekce. - Vyhodnocení výrazu se zpracovává, jak je popsáno v následující části.
Použití vyhodnocení výrazu
Standardní ladicí program Pythonu umožňuje vyhodnocení libovolných výrazů Pythonu v oknech Kukátku a Okamžité , pokud je laděný proces pozastavený v libovolném bodě kódu, pokud není blokován v vstupně-výstupní operaci nebo jiném podobném systémovém volání. V ladění ve smíšeném režimu lze libovolné výrazy vyhodnotit pouze v případě, že se zastaví v kódu Pythonu, po zarážce nebo při přechodu do kódu. Výrazy lze vyhodnotit pouze ve vlákně, na kterém došlo k zarážce nebo operaci krokování.
Když se ladicí program zastaví v nativním kódu nebo v kódu Pythonu, kde se popsané podmínky nepoužijí, například po operaci krokování nebo v jiném vlákně). Vyhodnocení výrazů je omezené na přístup k místním a globálním proměnným v oboru aktuálně vybraného rámce, přístupu k jejich polím a indexování předdefinovaných typů kolekcí pomocí literálů. Například následující výraz lze vyhodnotit v libovolném kontextu (za předpokladu, že všechny identifikátory odkazují na existující proměnné a pole odpovídajících typů):
foo.bar[0].baz['key']
Ladicí program smíšeného režimu také tyto výrazy překládá odlišně. Všechny operace přístupu členů vyhledávají pouze pole, která jsou přímo součástí objektu (například položka v jeho __dict__
objektu nebo __slots__
nebo pole nativní struktury vystavené Pythonu prostřednictvímtp_members
) a ignorují libovolnou __getattr__
__getattribute__
logiku , nebo popisovače. Podobně všechny operace indexování ignorují __getitem__
a přistupují přímo k vnitřním datovým strukturám kolekcí.
V zájmu konzistence se toto schéma překladu názvů používá pro všechny výrazy, které odpovídají omezením pro vyhodnocení omezeného výrazu. Toto schéma se použije bez ohledu na to, zda jsou v aktuálním bodu zastavení povoleny libovolné výrazy. Pokud chcete vynutit správnou sémantiku Pythonu, pokud je k dispozici plnohodnotný vyhodnocovací modul, uzavřete výraz do závorek:
(foo.bar[0].baz['key'])