Postupy: Migrace do prostředí /clr
Toto téma popisuje problémy, které vznikají při kompilaci nativního kódu s /clr (další informace, viz /clr (Common Language Runtime)./clr umožňuje modulům Visual C++ vyvolat se a být vyvolán z rozhraní sestavení .NET a přitom zachovat kompatibilitu s nespravovanými moduly.Viz Smíšená (nativní a spravovaná) sestavení a Nativní funkce a vzájemná funkční spolupráce rozhraní .NET další informace o výhodách kompilace s /clr.
Známé problémy kompilace projektů knihovny s /clr
Visual Studio obsahuje některé známé problémy, při kompilaci projektů knihovny s /clr:
Váš kód může dotazovat typy za běhu s CRuntimeClass::FromName.Avšak pokud je typ v jazyku MSIL.dll (kompilace s /clr), volání CRuntimeClass::FromName může selhat v případě, že k ní dojde před spuštěním statického konstruktoru ve spravované knihovně dll (neuvidíte tento problém v případě, že FromName volání provedení kódu je ve spravované knihovně DLL).Chcete-li tento problém vyřešit, můžete vynutit konstrukce staticky spravovaného konstruktoru definovaný funkcemi ve spravované knihovně .dll, jeho exportem a vyvoláním ho z nativní aplikace knihovny MFC.Příklad:
// Extension DLL Header file: __declspec( dllexport ) void EnsureManagedInitialization () { // managed code that won't be optimized away System::GC::KeepAlive(System::Int32::MaxValue); }
Kompilace v jazyce Visual C++
Před použitím volby /clr pro libovolný modul ve vašem projektu, nejprve zkompilujte a propojte váš nativní projekt pomocí systému Visual Studio 2010.
Následující kroky, následované v pořadí poskytují nejjednodušší cestu ke kompilaci /clr.Je to důležité ke kompilaci a spuštění Vašeho projektu po každém z těchto kroků.
Verze předcházející Visual C++ 2003
Pokud provádíte upgrade na systém Visual Studio 2010 z verze před jazykem Visual C++ 2003, mohou se objevit chyby při kompilaci vztahující se k vylepšením standardního jazyka C++ v jazyce Visual C++ 2003.
Inovace z aplikace Visual C++ 2003
Předchozí projekty sestavené pomocí jazyka Visual C++ 2003 by měly být nejprve zkompilovány bez volby /clr, protože systém Visual Studio nyní vylepšuje shodu se standardy ANSI/ISO a odstraňuje některé narušující změny.Změna, která bude pravděpodobně vyžadovat největší pozornost je Funkce zabezpečení v CRT.Kód, který používá CRT velmi pravděpodobně produkuje odmítání upozornění.Tato upozornění mohou být potlačena, ale přenesení do nové Verze funkcí CRT se zdokonaleným zabezpečením je upřednostňována, protože poskytuje lepší zabezpečení a může odhalit problémy bezpečnostní problematiku ve Vašem kódu.
Upgradování ze spravovaných rozšíření jazyka C++
Projekty vytvořené pomocí Visual C++ .NET nebo Visual C++ 2003, které používají Spravované rozšíření jazyka C++ budou vyžadovat alespoň jednu změnu nastavení projektu, jako tyto rozšíření jsou nyní zastaralá.V důsledku toho nebude kód zapsaný se Spravovaným rozšířením jazyka C++ chtít kompilaci menší než /clr.Jako náhradu použijte /clr:oldSyntax.
Převedení kódu jazyka C do jazyka C++
Přestože systém Visual Studio soubory jazyka C zkompiluje, je nutné je pro kompilaci pomocí volby /clr převést na jazyk C++.Skutečný název souboru nemusí být změněn, lze použít volbu /Tp (Další informace naleznete v tématu /Tc, /Tp, /TC, /TP (zadání typu zdrojového souboru).) Všimněte si, že ačkoli jsou soubory zdrojového kódu jazyka C++ pro volbu /clr vyžadovány, není nutné kód refaktorovat pro použití objektově orientovaných paradigmat.
Kód jazyka C je velmi pravděpodobně vyžadován ke změnám při kompilaci jako soubor jazyka C++.Pravidla bezpečnosti typů jazyka C++ jsou přísné, tak převody musí být vyrobeny explicitně s vysíláním.Například malloc vrací neplatný ukazatel, ale nemůže být přiřazen k ukazateli na libovolný typ v jazyce C s vysíláním:
int* a = malloc(sizeof(int)); // C code
int* b = (int*)malloc(sizeof(int)); // C++ equivalent
Funkce ukazatelů jsou také přísně bezpečné typy v jazyce C++, takže následující kód jazyka C vyžaduje změnu.V jazyce C++ je nejlepší vytvořit typedef , který definuje typ ukazatele funkce a potom pomocí typu odevzdaných ukazatelů funkcí:
NewFunc1 = GetProcAddress( hLib, "Func1" ); // C code
typedef int(*MYPROC)(int); // C++ equivalent
NewFunc2 = (MYPROC)GetProcAddress( hLib, "Func2" );
Jazyk C++ také vyžaduje, aby funkce byly buď prototypem nebo plně definované dříve, než mohou být vyvolány či odkazovány.
Identifikátory použité v kódu jazyka C, které se stanou klíčovými slovy v jazyce C++ (například virtual, new, delete, bool, true, false atd.) musí být přejmenovány.Toto může být obecně provedeno s jednoduchými operacemi vyhledávání a nahrazování.
Konečně vzhledem k tomu, že volání jazyka C styl modelu COM vyžaduje explicitní použití tabulky-v a ukazatel this, C++ nepodporuje:
COMObj1->lpVtbl->Method(COMObj, args); // C code
COMObj2->Method(args); // C++ equivalent
Opakovaná konfigurace nastavení projektu
Poté co se váš projekt v systému Visual Studio 2010 zkompiluje a spustí, byste měli, spíše než změnit výchozí konfigurace, vytvořit nové konfigurace projektu pro volbu /clr./clr není kompatibilní s možnostmi kompilátoru a umožňuje vytvoření samostatných konfigurací vytváření Vašeho projektu jako nativní nebo spravované.Když je /clr vybrán ve vlastnostech stránky dialogového okna, nastavení projektu není kompatibilní s /clr jsou neaktivní (a neaktivní možnosti nebudou automaticky obnoveny pokud /clr je následně nevybrané).
Vytvořit nové konfigurace projektu
Můžete použít volbu Kopírovat nastavení z v Dialogové okno Konfigurace nového projektu chcete-li vytvořit projekt konfigurace na základě existujícího nastavení projektu.Provést to jednou pro konfiguraci ladění a jednou pro vydanou verzi konfigurace.Následné změny potom mohou být použity k /clr -pouze zvláštní konfigurace ponechá původní konfigurace projektu beze změny.
Projekty, používající vlastní pravidla sestavení mohou vyžadovat zvláštní pozornost.
Tento krok má různé důsledky pro projekty, používající makefiles.V tomto případě lze nakonfigurovat samostatnou cílovou databázi sestavení nebo verze, které jsou specifické pro kompilaci /clr, která může být vytvořena z kopie originálu.
Změna nastavení projektu
/clr můžou být vybrány ve vývojovém prostředí postupujícím podle pokynů v /clr (Common Language Runtime).Jak již bylo zmíněno dříve, tento krok automaticky zakáže konfliktní nastavení projektu.
[!POZNÁMKA]
Při upgradu spravované knihovny nebo projektu webové služby z jazyka Visual C++ 2003 na jazyk Visual C++ 2005, bude na stránku vlastností Příkazový řádek přidána volba kompilátoru /Zl.Tento postup způsobí LNK2001.Odstranění /Zl z Příkazový řádek vlastnost stránky k přeložení.Další informace naleznete v tématu /Zl (vypuštění názvu výchozí knihovny) a Postupy: Otevření stránek vlastností projektu.Nebo přidat msvcrt.lib a msvcmrt.lib do propojovacího programu vlastnosti Další závislosti.
Pro projekty vytvořené pomocí makefiles nekompatibilní možnosti kompilátoru musí být zakázána ruční /clr je přidána.Viz //clr – omezení informace o možnostech kompilátoru, které nejsou kompatibilní s /clr.
Předkompilované hlavičky
Předkompilovaná záhlaví jsou podporována v rámci /clr.Avšak v případě, že kompilujete pouze některé kompilované soubory CPP s /clr (kompilování zbytku jako nativní), budou některé změny požadovány, protože předkompilovaná záhlaví generovaná s /clr nejsou kompatibilní se záhlavími generovanými bez /clr.Tato nekompatibilita je způsobena faktem, že /clr generuje a vyžaduje metadata.Kompilované moduly /clr proto nelze použít předkompilovanou hlavičku, která nezahrnuje metadata a moduly /clr nelze použít předkompilované hlavičky souborů, které neobsahují metadata.
Nejjednodušší způsob sestavení projektu, kde jsou některé moduly zkompilovány /clr, je zcela zakázat předkompilované hlavičky. (V dialogovém okně projektu vlastnosti stránky otevřete uzel C/C++ a vyberte předkompilované záhlaví.Potom změňte hodnotu vlastnosti Vytvořit/použít předkompilovaná záhlaví na hodnotu Nepoužívá předkompilovaná záhlaví.)
Nicméně, zvláště pro velké projekty předkompilovaná záhlaví poskytují mnohem lepší rychlost kompilace proto zakázání této funkce není žádoucí.V tomto případě je nejlepší ke konfiguraci /clr a non /clr soubory pro použití samostatných předkompilovaných záhlaví.To lze provést v jednom kroku výběrem více modulů ke kompilaci /clr pomocí Průzkumníka řešení, kliknutím pravým tlačítkem myši na skupinu a výběrem příkazu Vlastnosti.Poté změňte obě vlastnosti Vytvořit/použít PCH pomocí souboru a Soubor překompilovaného záhlaví na použití jiného názvu souboru záhlaví a souboru PCH.
Oprava chyb
Kompilace s /clr může mít za následek v kompilátoru propojovací program nebo chyby runtime.Tato část popisuje nejběžnější problémy.
Sloučení metadat
Rozdílné verze typů dat můžou způsobit, že se propojovací program nezdaří, protože jsou generovány pro dva typy neodpovídajících metadat. (To je obvykle způsobeno, když členové typu jsou podmíněně definovány, ale podmínky nejsou stejné pro všechny soubory CPP, které používají typ.) V tomto případě propojovací program selže, pouze vykazování názvu druhého souboru OBJ, kde byl definován typ.Je to často užitečné k rotaci pořadí, aby OBJ soubory odesílány propojovací program k zajištění umístění ostatní verze datového typu.
Načítání vzájemného zablokování zámku
V aplikaci Visual C++ .NET a Visual C++ 2003 byla inicializace pod /clr byla náchylná k nedeterministickému bloku.Tento problém je označován jako "načítání vzájemného zablokování".V systému Visual Studio 2010 se lze tomuto vzájemnému zablokování snadněji vyhnout, jelikož je rozpoznáno a ohlášeno za běhu a již není deterministické.Vyskytování problému uzamknutí zavaděče je stále možné, ale nyní je mnohem jednodušší, aby se zabránilo a opravilo.Viz Inicializace smíšených sestavení pro podrobné pozadí, pokyny a řešení.
Data Exports
Export dat knihovny DLL je náchylné chybám a není doporučeno.Je to proto, že není zaručena inicializace oddílu dat knihovny DLL, dokud není spuštěna některá spravovaná část knihovny DLL.Odkazuje na metadata s #using – direktiva (C++).
Typ viditelnosti
Nativní typy jsou nyní soukromé ve výchozím nastavení.Ve Visual C++ .NET 2002 a Visual C++ 2003, byly nativní typy veřejné ve výchozím nastavení.Ve výsledku to nemusí být v nativním typu viditelné mimo knihovnu DLL.Řešením této chyby přidáním public k těmto typům.Další informace naleznete v tématu Typ a viditelnost členské.
Plovoucí desetinná čárka a přidružené problémy.
__controlfp není podporován v modulu CLR ( Common Language Runtime ) ( více informací naleznete u ovládacích prvků _control87, _controlfp, __control87_2 ).CLR také nerespektuje align (C++).
Inicializace modulu COM
Modul CLR (Common Language Runtime) inicializuje model COM při inicializaci modulu (když je model COM inicializován automaticky, probíhá tento proces stejně jako MTA).V důsledku toho explicitní inicializace modelu COM vytváří návratové kódy označující, že model COM je již inicializován.Pokus o explicitní inicializaci modelu COM pro určitý model vláken, když modul CLR již inicializoval model COM pro jiný model vláken, může způsobit selhání aplikace.
Modul CLR (Common Language Runtime) spustí ve výchozím nastavení model COM jako model MTA. Pokud chcete toho chování změnit, použijte atribut /CLRTHREADATTRIBUTE (Nastavit atribut vlákna modulu CLR).
Problémy s výkonem
Můžete zaznamenat snížení výkonu, když jsou nativní metody jazyka C++ generované do jazyka MSIL volány nepřímo (virtuální funkce volají nebo používají funkce ukazatele).Další informace naleznete v tématu Dvojitý převod adres na jinou bitovou šířku (C++).
Při přesunu z nativního do jazyka MSIL, zjistíte zvýšení velikosti Vaší pracovní sady.Důvodem je, že modul CLR (common language runtime) poskytuje mnoho funkcí, aby programy běžely správně.Pokud vaše aplikace /clr není spuštěna správně, možná budete chtít povolit C4793 (vypnutí ve výchozím nastavení), další informace,viz Upozornění kompilátoru (úroveň 1 a 3) C4793.
Chyba programu během vypnutí
V některých případech může CLR vypnout před Vaším dokončením spuštění spravovaného kódu.Použitím std::set_terminate a to může způsobit SIGTERM.Další informace naleznete v tématu signal – konstanty a set_terminate (<exception>).
Použití nové funkce aplikace Visual C++
Po kompilaci, propojení a spuštění aplikace můžete začít používat funkce .NET v jakémkoliv kompilovaném modulu s /clr.Další informace naleznete v tématu Rozšíření komponent pro platformy běhového prostředí.
Pokud jste použili spravované rozšíření jazyka C++, můžete převést Váš kód k použití nové syntaxe.Souhrn syntaktických rozdílů naleznete v odkazu Managed Extensions for C++ Syntax Upgrade Checklist.Detaily o převodu spravovaného rozšíření jazyka C++ naleznete v tématu Základy migrace v jazyku C++/CLI.
Informace o programování v jazyce Visual C++ .NET naleznete v následujících tématech: