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í nemůže být argumenty funkce /clr/clr spravovaného typu.

Příklad správného podpisu:

// managed_types_and_main.cpp
// compile with: /clr
int main(int, char*[], char*[]) {}

.NET Framework ekvivalenty nativních typů jazyka C++

Následující tabulka uvádí klíčová slova pro předdefinované typy Visual C++, což jsou aliasy předdefinovaných typů v oboru názvů System.

Visual C++ typu 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 intlong , 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 na výchozí hodnotu nebo najdete v signed charunsigned char tématu signed char

Problémy s verzí pro typy hodnot vnořené v nativních typech

Vezměte v úvahu podepsanou komponentu sestavení (silný název) použitou k sestavení sestavení klienta. Komponenta obsahuje typ hodnoty, který se používá v klientovi jako typ pro člena nativního sjednoceného, 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 ( ).

Příklad

Následující ukázka je komponenta .

// 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 ale do souboru nested_value_types.cpp přidáte dalšího člena (například ) a komponentu znovu zkompilujete bez opětovné kompilace klienta, výsledkem je neošetřená struct Sdouble d; výjimka (typu struct S).

Postupy: Testování rovnosti

V následující ukázce je test rovnosti, který používá Spravovaná rozšíření jazyka C++, založen na tom, na co popisovače odkazují.

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)

Postupy: Diagnostika a oprava problémů s kompatibilitou sestavení

Toto téma vysvětluje, co se může stát, když verze sestavení odkazovaná v době kompilace neodpovídá verzi sestavení odkazované za běhu a jak se problému vyhnout.

Při kompilaci sestavení lze pomocí syntaxe odkazovat na jiná #using sestavení. Během kompilace jsou k těmto sestavením přistupováno kompilátorem. Informace z těchto sestavení slouží k rozhodování o optimalizaci.

Pokud je však odkazované sestavení změněno a znovu zkompilováno a nelze znovu zkompilovat odkazované sestavení, které je na sestavení závislé, sestavení nemusí být stále kompatibilní. Rozhodnutí o optimalizaci, která byla na první pohled platná, nemusí být s ohledem na novou verzi sestavení správná. Kvůli těmto nekompatibility může dojít k různým chybám za běhu. 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á problém způsobila.

Tyto chyby by neměly být problémem v konečném produkčním kódu, pokud je celá aplikace znovu sestavena pro vydanou verzi vašeho produktu. Sestavení, která jsou vydána pro veřejnost, by měla být označena oficiálním číslem verze, které zajistí, že se těmto problémům zabrání. Další informace najdete v tématu o verzích sestavení.

Diagnostika a oprava chyby nekompatibilita

  1. Pokud narazíte na výjimky modulu runtime nebo jiné chybové stavy, ke kterým dochází v kódu, který odkazuje na jiné sestavení a které nemají žádnou jinou identifikované příčinu, je možné, že pracujete se sestavením, které je zastaralé.

  2. Nejprve výjimku nebo jiný chybový stav izolovat a reprodukovat. Problém, ke kterému dochází kvůli zastaralé výjimce, by měl být reprodukovatelný.

  3. Zkontrolujte časové razítko všech sestavení odkazovaných ve vaší aplikaci.

  4. Pokud jsou časová razítka jakýchkoli odkazovaných sestavení pozdější než časové razítko poslední kompilace vaší aplikace, pak je vaše aplikace neaktuály. Pokud k tomu dojde, zkompilujte aplikaci s nejnovějším sestavením a proveďte všechny požadované změny kódu.

  5. Spusťte aplikaci znovu, proveďte kroky, které problém reprodukují, a ověřte, že k výjimce nedochází.

Příklad

Následující program znázorňuje problém omezením přístupnosti metody a pokusem o přístup k této metodě v jiném sestavení bez opětovného dokončování. Zkuste nejprve changeaccess.cpp kompilovat. Toto je odkazované sestavení, které se změní. Pak zkompilujte referencing.cpp . Kompilace bude úspěšná. Teď zmenšete přístupnost zvané metody . Znovu changeaccess.cpp zkompilujte pomocí příznaku /DCHANGE_ACCESS . Díky tomu je metoda chráněná, nikoli soukromá, takže ji lze volat déle z právních předpisů. Bez opětovného referencing.exe dokončování spusťte aplikaci znovu. Výsledkem bude výjimka MethodAccessException.

// 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;
  }

};
// 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í pro .NET v jazyce C++/CLI (Visual C++)
Vzájemná funkční spolupráce s jinými jazyky rozhraní .NET (C++/CLI)
Spravované typy (C++/CLI)
#using – direktiva