Share via


Postupy: Migrace na /clr

Tento článek popisuje problémy, ke kterým dochází při kompilaci nativního kódu s /clr. (Další informace naleznete v tématu /clr (Common Language Runtime Compilation).) /clr umožňuje nativní kód jazyka C++ vyvolat a vyvolat z sestavení .NET kromě jiného nativního kódu jazyka C++. Další informace o výhodách kompilace pomocí /clr, viz smíšené (nativní a spravované) sestavení a nativní a .NET interoperability.

Známé problémy při kompilaci projektů knihovny pomocí /clr

Visual Studio obsahuje některé známé problémy při kompilaci projektů knihovny pomocí /clr:

  • Kód může za běhu CRuntimeClass::FromNamedotazovat typy. Pokud je však typ v knihovně MSIL DLL (kompilováno pomocí /clr), může volání FromName selhat, pokud dojde před spuštěním statických konstruktorů ve spravované knihovně DLL. (Tento problém se nezobrazí, pokud se FromName volání stane po spuštění kódu ve spravované knihovně DLL.) Chcete-li tento problém vyřešit, můžete vynutit vytvoření spravovaného statického konstruktoru: definovat funkci ve spravované knihovně DLL, exportovat ji a vyvolat ji z nativní aplikace MFC. Příklad:

    // MFC 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 /clr libovolného modulu v projektu nejprve zkompilujte a propojte svůj nativní projekt se sadou Visual Studio.

Následující kroky, následované v pořadí, poskytují nejjednodušší cestu k /clr kompilaci. Po každém z těchto kroků je důležité zkompilovat a spustit projekt.

Upgrade ze starších verzí sady Visual Studio

Pokud upgradujete Visual Studio ze starší verze, můžou se v sadě Visual Studio zobrazit chyby kompilátoru související s vylepšeným standardem C++.

Projekty vytvořené se staršími verzemi sady Visual Studio by se měly nejprve zkompilovat i bez /clr. Visual Studio teď zvýšilo shodu standardu C++ a některé zásadní změny. Změny, které pravděpodobně vyžadují největší pozornost, jsou funkce zabezpečení v CRT. Kód, který používá CRT, pravděpodobně způsobí upozornění na vyřazení. Tato upozornění je možné potlačit, ale migrace na nové verze funkcí CRT s rozšířeným zabezpečením je upřednostňovaná, protože poskytují lepší zabezpečení a můžou odhalit problémy se zabezpečením ve vašem kódu.

Upgrade z Spravovaná rozšíření jazyka C++

V sadě Visual Studio 2005 a novějších verzích se kód napsaný pomocí Spravovaná rozšíření jazyka C++ nebude kompilovat v části /clr.

Převod kódu jazyka C na C++

I když Visual Studio kompiluje soubory jazyka C, je nutné je převést na jazyk C++ pro /clr kompilaci. Skutečný název souboru nemusí být změněn; můžete použít /Tp (viz/Tc , /Tp, /TC, , /TP (Zadat typ zdrojového souboru).) I když jsou pro soubory zdrojového kódu C++ potřeba /clr, není nutné refaktorovat kód tak, aby používal objektově orientované paradigmata.

Kód jazyka C bude pravděpodobně vyžadovat změny při kompilaci jako souboru C++. Pravidla zabezpečení typu C++ jsou striktní, takže převody typů musí být explicitní s přetypování. Například malloc vrátí ukazatel void, ale lze ho přiřadit k libovolnému typu v jazyce C s přetypování:

int* a = malloc(sizeof(int));   // C code
int* b = (int*)malloc(sizeof(int));   // C++ equivalent

Ukazatele funkcí jsou v jazyce C++ také přísně typově bezpečné, takže následující kód jazyka C vyžaduje úpravy. V jazyce C++ je nejlepší vytvořit typedef definici typu ukazatele funkce a pak tento typ použít k přetypování ukazatelů na funkce:

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 prototypovány nebo plně definovány dříve, než je lze odkazovat nebo vyvolat.

Identifikátory používané v kódu jazyka C, které se v jazyce C++ používají jako klíčová slova (například virtual, new, delete, bool, true, falseatd.), musí být přejmenovány. Tuto změnu lze obecně provést pomocí jednoduchých operací hledání a nahrazení.

COMObj1->lpVtbl->Method(COMObj, args);  // C code
COMObj2->Method(args);  // C++ equivalent

Změna konfigurace nastavení projektu

Po kompilaci a spuštění projektu v sadě Visual Studio byste měli místo úprav výchozích konfigurací vytvořit nové konfigurace /clr projektu. /clr není kompatibilní s některými možnostmi kompilátoru. Vytváření samostatných konfigurací umožňuje sestavit projekt jako nativní nebo spravovaný. Pokud /clr je vybrána v dialogovém okně stránky vlastností, nastavení projektu není kompatibilní s /clr jsou zakázána. (Zakázané možnosti se automaticky neobnoví, pokud /clr je později nevybrané.)

Vytvoření nových konfigurací projektu

Pomocí možnosti Kopírovat Nastavení Z v dialogovém okně Nová konfigurace projektu (Nová konfigurace> aktivního řešení sestavení>nástroje Configuration Manager>) můžete vytvořit konfiguraci projektu na základě stávajícího nastavení projektu. Vytvořte kopii konfigurace jednou pro konfiguraci ladění a jednou pro konfiguraci vydané verze. Následné změny se pak dají použít pouze u /clrkonfigurací specifických pro konkrétní, takže původní konfigurace projektu zůstanou nedotčené.

Projekty, které používají vlastní pravidla sestavení, mohou vyžadovat zvláštní pozornost.

Tento krok má různé důsledky pro projekty, které používají soubory pravidel. V takovém případě je možné nakonfigurovat samostatný cíl sestavení nebo z kopie originálu lze vytvořit verzi specifickou pro /clr kompilaci.

Změna nastavení projektu

/clr je možné vybrat ve vývojovém prostředí podle pokynů v /clr (Common Language Runtime Compilation). Jak už 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 ze sady Visual Studio 2003 se možnost kompilátoru /Zl přidá na stránku vlastností příkazového řádku . To způsobuje chyby LNK2001. Pokud chcete chyby vyřešit, odeberte /Zl ze stránky vlastností příkazového řádku . Další informace najdete v tématu /Zl (Vynechání výchozího názvu knihovny) a nastavení vlastností kompilátoru a sestavení.

U projektů vytvořených pomocí souborů pravidel je nutné po přidání ručně /clr zakázat nekompatibilní možnosti kompilátoru. Informace o možnostech kompilátoru, které nejsou kompatibilní /clr, najdete v tématu /clr Omezení.

Předkompilované hlavičky

Předkompilované hlavičky jsou podporovány v části /clr. Pokud ale zkompilujete jenom některé soubory CPP ( /clr kompilujete zbytek jako nativní), vyžadují se některé změny. Předkompilované hlavičky generované pomocí /clr předkompilovaných hlaviček nejsou kompatibilní s předkompilovanými hlavičkami vygenerovanými bez /clr, protože /clr generuje a vyžaduje metadata. Moduly zkompilované pomocí /clr předkompilovaných hlaviček, které neobsahují metadata,/clr nemůžou používat předkompilované hlavičkové soubory, které obsahují metadata.

Nejjednodušší způsob, jak zkompilovat projekt, se /clr kterým jsou některé moduly zkompilovány, je zcela zakázat předkompilované hlavičky. (V dialogovém okně Stránky vlastností projektu otevřete Uzel C/C++ a vyberte Předkompilované hlavičky. Potom změňte vlastnost Create/Use Precompiled Headers na "Not Using Precompiled Headers".)

Zejména u velkých projektů ale předkompilované hlavičky poskytují mnohem lepší rychlost kompilace, takže zakázání této funkce není žádoucí. V tomto případě je nejlepší nakonfigurovat /clr soubory/clr bez souborů tak, aby používaly samostatné předkompilované hlavičky. Můžete je nakonfigurovat v jednom kroku: Vícenásobný výběr modulů, které /clr se mají zkompilovat pomocí Průzkumník řešení. Klikněte pravým tlačítkem na skupinu a vyberte Vlastnosti. Potom změňte vlastnosti Create/Use PCH Through File a Prekompiled Header File tak, aby používaly jiný název hlavičkového souboru a soubor PCH.

Oprava chyb

Kompilace kódu může vést k chybám /clr kompilátoru, linkeru nebo modulu runtime. Tato část popisuje nejběžnější problémy.

Sloučení metadat

Rozdílové verze datových typů můžou způsobit selhání linkeru, protože metadata generovaná pro tyto dva typy se neshodují. (K chybám dochází při podmíněném definování členů typu, ale podmínky nejsou stejné pro všechny soubory CPP, které používají typ.) V tomto případě linker selže a hlásí pouze název symbolu a název druhého souboru OBJ, ve kterém byl typ definován. Může být užitečné otočit pořadí odesílání souborů OBJ do linkeru, abyste zjistili umístění jiné verze datového typu.

Zámek zavaděče

K zablokování zámku zavaděče může dojít, ale je deterministické a je zjištěno a hlášeno za běhu. Podrobné pokyny a řešení najdete v tématu Inicializace smíšených sestavení .

Exporty dat

Export dat knihovny DLL je náchylný k chybám a nedoporučuje se v /clr kódu. Je to proto, že inicializace datového oddílu knihovny DLL není zaručena, dokud se nespustí některá spravovaná část knihovny DLL. Referenční metadata s direktivami#using.

Viditelnost typů

Nativní typy jsou private ve výchozím nastavení. Nativní private typ není viditelný mimo knihovnu DLL. Vyřešte tuto chybu přidáním public do těchto typů.

Problémy s plovoucí desetinou čárkou a zarovnáním

__controlfp v modulu CLR (Common Language Runtime) se nepodporuje. (Další informace naleznete v tématu _control87, _controlfp__control87_2.) CLR také nerespektuje align.

Inicializace modelu COM

Modul CLR (Common Language Runtime) inicializuje model COM automaticky při inicializaci modulu (když se com inicializuje automaticky, tak jako MTA). V důsledku toho explicitně inicializace modelu COM vrací návratové kódy označující, že com je již inicializován. Pokus o explicitní inicializaci modelu COM s jedním modelem vláken, pokud clR již inicializoval model COM do jiného modelu vláken, může způsobit selhání vaší aplikace.

Modul CLR (Common Language Runtime) ve výchozím nastavení spouští model COM jako MTA; k úpravě modelu COM použijte /CLRTHREADATTRIBUTE (nastavit atribut vlákna CLR).

Problémy s výkonem

Snížení výkonu se může zobrazit, když se nativní metody jazyka C++ vygenerované do jazyka MSIL volají nepřímo (prostřednictvím volání virtuálních funkcí nebo pomocí ukazatelů funkcí). Další informace najdete v tématu Double Thunking.

Když přejdete z nativního prostředí na jazyk MSIL, všimnete si zvýšení velikosti pracovní sady. K tomuto zvýšení dochází, protože modul CLR (Common Language Runtime) poskytuje mnoho funkcí, které zajišťují správné spuštění programů. Pokud vaše /clr aplikace nefunguje správně, možná budete chtít povolit upozornění kompilátoru mimo výchozí nastavení (úroveň 1 a 3) C4793.

Při vypnutí dojde k chybovému ukončení programu

V některých případech může modul CLR vypnout před dokončením spuštění spravovaného kódu. std::set_terminate Použití a SIGTERM může způsobit vypnutí. Další informace naleznete v tématu signal konstanty a set_terminate.

Použití nových funkcí jazyka Visual C++

Po kompilaci aplikace, propojení a spuštění můžete začít používat funkce .NET v libovolném modulu zkompilovaném pomocí /clr. Další informace naleznete v tématu Rozšíření komponent pro platformy modulu runtime.

Další informace o programování v .NET v jazyce Visual C++najdete tady:

Viz také

Smíšená (nativní a spravovaná) sestavení