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, longa 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 charnaleznete 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.

  1. 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ý.

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

  3. 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.

  4. 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_ACCESSkompilátoru . Je to access_me metoda , nikoli public, takže nelze volat z vnější Test nebo protectedjeho deriváty. Bez opětovného zkompilování referencing.exespusť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