Spravované typy (C++/CLI)
Visual C++ umožňuje přístup k funkcím .NET prostřednictvím spravovaných typů, které poskytují podporu funkcí modulu CLR (Common Language Runtime) a podléhají výhodám a omezením modulu runtime.
Spravované typy a hlavní funkce
Při psaní aplikace pomocí /clr
, argumenty main()
funkce nemohou být spravovaného typu.
Příkladem správného podpisu je:
// managed_types_and_main.cpp
// compile with: /clr
int main(int, char*[], char*[]) {}
Ekvivalenty rozhraní .NET Framework nativním typům jazyka C++
Následující tabulka ukazuje klíčová slova pro předdefinované typy Visual C++, což jsou aliasy předdefinovaných typů v oboru názvů Systému .
Typ Jazyka Visual C++ | Typ rozhraní .NET Framework |
---|---|
void |
System.Void |
bool |
System.Boolean |
signed char |
System.SByte |
unsigned char |
System.Byte |
wchar_t |
System.Char |
short a signed short |
System.Int16 |
unsigned short |
System.UInt16 |
int , signed int , long a signed long |
System.Int32 |
unsigned int a unsigned long |
System.UInt32 |
__int64 a signed __int64 |
System.Int64 |
unsigned __int64 |
System.UInt64 |
float |
System.Single |
double a long double |
System.Double |
Další informace o možnosti kompilátoru pro výchozí hodnotu signed char
nebo unsigned char
naleznete v tématu /J
(Výchozí char
typ je unsigned
).
Problémy s verzí typů hodnot vnořených v nativních typech
Vezměte v úvahu podepsanou (silnou název) součást sestavení, která se používá k sestavení klientského sestavení. Komponenta obsahuje typ hodnoty, který se v klientovi používá jako typ člena nativní sjednocení, třídy nebo pole. Pokud budoucí verze komponenty změní velikost nebo rozložení typu hodnoty, musí být klient znovu zkompilován.
Vytvořte soubor klíčů pomocí sn.exe (sn -k mykey.snk
).
Příklad
Následující ukázka je součástí.
// nested_value_types.cpp
// compile with: /clr /LD
using namespace System::Reflection;
[assembly:AssemblyVersion("1.0.0.*"),
assembly:AssemblyKeyFile("mykey.snk")];
public value struct S {
int i;
void Test() {
System::Console::WriteLine("S.i = {0}", i);
}
};
Tato ukázka je klient:
// nested_value_types_2.cpp
// compile with: /clr
#using <nested_value_types.dll>
struct S2 {
S MyS1, MyS2;
};
int main() {
S2 MyS2a, MyS2b;
MyS2a.MyS1.i = 5;
MyS2a.MyS2.i = 6;
MyS2b.MyS1.i = 10;
MyS2b.MyS2.i = 11;
MyS2a.MyS1.Test();
MyS2a.MyS2.Test();
MyS2b.MyS1.Test();
MyS2b.MyS2.Test();
}
Příklad vytvoří tento výstup:
S.i = 5
S.i = 6
S.i = 10
S.i = 11
Komentáře
Pokud však přidáte do struct S
nested_value_types.cpp
složky (například double d;
) dalšího člena a komponentu znovu zkompilujete bez opětovného zkompilování klienta, výsledkem je neošetřená výjimka (typu System.IO.FileLoadException).
Testování rovnosti
V následující ukázce je test rovnosti, který používá Spravovaná rozšíření jazyka C++, založený na popisovačích.
Příklad
// mcppv2_equality_test.cpp
// compile with: /clr /LD
using namespace System;
bool Test1() {
String ^ str1 = "test";
String ^ str2 = "test";
return (str1 == str2);
}
Il pro tento program ukazuje, že návratová hodnota je implementována pomocí volání op_Equality
.
IL_0012: call bool [mscorlib]System.String::op_Equality(string, string)
Jak diagnostikovat a opravit problémy s kompatibilitou sestavení
Pokud verze sestavení odkazovaného v době kompilace neodpovídá verzi sestavení, na které odkazuje za běhu, může dojít k různým problémům.
Při kompilaci sestavení lze na jiná sestavení odkazovat pomocí #using
syntaxe. Během kompilace jsou tato sestavení přístupná kompilátorem. Informace z těchto sestavení slouží k rozhodování o optimalizaci.
Pokud je však odkazované sestavení změněno a rekompilováno, překompilujte také odkazující sestavení, které je na něm závislé. V opačném případě mohou být sestavení nekompatibilní. Rozhodnutí o optimalizaci, která byla platná jako první, nemusí být správná pro novou verzi sestavení. K různým chybám za běhu může dojít kvůli těmto nekompatibilitě. V takových případech neexistuje žádná konkrétní výjimka. Způsob hlášení selhání za běhu závisí na povaze změny kódu, která způsobila problém.
Tyto chyby by neměly být v konečném produkčním kódu problém, pokud se celá aplikace znovu sestaví pro vydanou verzi produktu. Sestavení, která jsou vydána veřejnosti, by měla být označena oficiálním číslem verze, což zajistí, že se těmto problémům vyhnete. Další informace naleznete v tématu Správa verzí sestavení.
Diagnostika a oprava chyby nekompatibility
V kódu, který odkazuje na jiné sestavení, můžete narazit na výjimky za běhu nebo jiné chybové podmínky. Pokud nemůžete identifikovat jinou příčinu, může být problém zastaralým sestavením.
Nejprve izolujte a reprodukujte výjimku nebo jiný chybový stav. Problém, ke kterému dochází kvůli zastaralé výjimce, by měl být reprodukovatelný.
Zkontrolujte časové razítko všech sestavení odkazovaných v aplikaci.
Pokud jsou časové razítka všech odkazovaných sestavení pozdější než časové razítko poslední kompilace vaší aplikace, je vaše aplikace za aktuální. Pokud je zastaralý, znovu zkompilujte aplikaci s nejnovějšími sestaveními a v případě potřeby upravte kód.
Spusťte aplikaci znovu, proveďte kroky, které problém reprodukují, a ověřte, že k výjimce nedošlo.
Příklad
Následující program ukazuje problém: nejprve snižuje přístupnost metody a pak se pokusí získat přístup k této metodě v jiném sestavení bez rekompilování. Nejprve zkompilujte changeaccess.cpp
. Jedná se o odkazované sestavení, které se změní. Pak zkompilujte referencing.cpp
. Měl by se úspěšně zkompilovat. Dále zmenšete přístupnost volané metody. Překompilovat changeaccess.cpp
s možností /DCHANGE_ACCESS
kompilátoru . Je to access_me
metoda , nikoli public
, takže nelze volat z vnější Test
nebo protected
jeho deriváty. Bez opětovného zkompilování referencing.exe
spusťte aplikaci znovu. Dojde MethodAccessException k chybě.
// changeaccess.cpp
// compile with: /clr:safe /LD
// After the initial compilation, add /DCHANGE_ACCESS and rerun
// referencing.exe to introduce an error at runtime. To correct
// the problem, recompile referencing.exe
public ref class Test {
#if defined(CHANGE_ACCESS)
protected:
#else
public:
#endif
int access_me() {
return 0;
}
};
Tady je zdroj pro odkazující sestavení:
// referencing.cpp
// compile with: /clr:safe
#using <changeaccess.dll>
// Force the function to be inline, to override the compiler's own
// algorithm.
__forceinline
int CallMethod(Test^ t) {
// The call is allowed only if access_me is declared public
return t->access_me();
}
int main() {
Test^ t = gcnew Test();
try
{
CallMethod(t);
System::Console::WriteLine("No exception.");
}
catch (System::Exception ^ e)
{
System::Console::WriteLine("Exception!");
}
return 0;
}
Viz také
Programování v .NET pomocí C++/CLI (Visual C++)
Interoperabilita s jinými jazyky .NET (C++/CLI)
Spravované typy (C++/CLI)
#using
směrnice