Udostępnij za pośrednictwem


Przyjazne zestawy (C++)

W przypadku odpowiednich środowisk uruchomieniowych funkcja języka przyjaznych zestawów sprawia, że typy, które znajdują się w zakresie przestrzeni nazw lub zakresie globalnym w składniku zestawu dostępnym dla co najmniej jednego zestawu klienta lub modułów .netmodules.

Wszystkie środowiska wykonawcze

Uwagi

(Ta funkcja języka nie jest obsługiwana we wszystkich środowiskach uruchomieniowych).

Środowisko wykonawcze systemu Windows

Uwagi

(Ta funkcja języka nie jest obsługiwana w środowisko wykonawcze systemu Windows).

Wymagania

Opcja kompilatora: /ZW

środowiska uruchomieniowe w trakcie wykonania

Uwagi

Aby tworzyć typy w zakresie przestrzeni nazw lub zakresie globalnym w składniku zestawu dostępnym dla zestawu klienta lub .netmodule

  1. W składniku określ atrybut InternalsVisibleToAttributezestawu i przekaż nazwę zestawu klienta lub .netmodule, która będzie uzyskiwać dostęp do typów w zakresie przestrzeni nazw lub zakresie globalnym w składniku. Można określić wiele zestawów klienta lub modułów .netmodules, określając dodatkowe atrybuty.

  2. W zestawie klienta lub w trybie .netmodule podczas odwoływać się do zestawu składników przy użyciu polecenia #using, przekaż as_friend atrybut . Jeśli określisz as_friend atrybut zestawu, który nie określi InternalsVisibleToAttribute, zostanie zgłoszony wyjątek środowiska uruchomieniowego, jeśli spróbujesz uzyskać dostęp do typu w zakresie przestrzeni nazw lub zakresie globalnym w składniku.

Błąd kompilacji spowoduje, że zestaw zawierający InternalsVisibleToAttribute atrybut nie ma silnej nazwy, ale zestaw klienta, który używa atrybutu as_friend .

Mimo że typy w zakresie przestrzeni nazw i zakresie globalnym mogą być znane zestawowi klienta lub modułowi .netmodule, dostępność składowa jest nadal obowiązująca. Na przykład nie można uzyskać dostępu do prywatnego elementu członkowskiego.

Należy jawnie udzielić dostępu do wszystkich typów w zestawie. Na przykład zestaw C nie ma dostępu do wszystkich typów w zestawie A, jeśli zestaw C odwołuje się do zestawu B i zestaw B ma dostęp do wszystkich typów w zestawie A.

Aby uzyskać informacje o sposobie podpisywania — czyli nadawaniu silnej nazwy — zestawowi kompilatorowi języka Microsoft C++, zobacz Zestawy silnych nazw (podpisywanie zestawów) (C++/CLI).

Alternatywą dla używania funkcji zestawów przyjaznych jest StrongNameIdentityPermission ograniczenie dostępu do poszczególnych typów.

Wymagania

Opcja kompilatora: /clr

Przykłady

Poniższy przykład kodu definiuje składnik, który określa zestaw klienta, który ma dostęp do typów w składniku.

// friend_assemblies.cpp
// compile by using: /clr /LD
using namespace System::Runtime::CompilerServices;
using namespace System;
// an assembly attribute, not bound to a type
[assembly:InternalsVisibleTo("friend_assemblies_2")];

ref class Class1 {
public:
   void Test_Public() {
      Console::WriteLine("Class1::Test_Public");
   }
};

Następny przykład kodu uzyskuje dostęp do typu prywatnego w składniku.

// friend_assemblies_2.cpp
// compile by using: /clr
#using "friend_assemblies.dll" as_friend

int main() {
   Class1 ^ a = gcnew Class1;
   a->Test_Public();
}
Class1::Test_Public

Następny przykład kodu definiuje składnik, ale nie określa zestawu klienta, który będzie miał dostęp do typów w składniku.

Zwróć uwagę, że składnik jest połączony przy użyciu / opt:noref. Gwarantuje to, że typy prywatne są emitowane w metadanych składnika, co nie jest wymagane, gdy InternalsVisibleTo atrybut jest obecny. Aby uzyskać więcej informacji, zobacz /OPT (Optymalizacje).

// friend_assemblies_3.cpp
// compile by using: /clr /LD /link /opt:noref
using namespace System;

ref class Class1 {
public:
   void Test_Public() {
      Console::WriteLine("Class1::Test_Public");
   }
};

Poniższy przykład kodu definiuje klienta, który próbuje uzyskać dostęp do typu prywatnego w składniku, który nie daje dostępu do jego typów prywatnych. Ze względu na zachowanie środowiska uruchomieniowego, jeśli chcesz przechwycić wyjątek, musisz spróbować uzyskać dostęp do typu prywatnego w funkcji pomocniczej.

// friend_assemblies_4.cpp
// compile by using: /clr
#using "friend_assemblies_3.dll" as_friend
using namespace System;

void Test() {
   Class1 ^ a = gcnew Class1;
}

int main() {
   // to catch this kind of exception, use a helper function
   try {
      Test();
   }
   catch(MethodAccessException ^ e) {
      Console::WriteLine("caught an exception");
   }
}
caught an exception

W następnym przykładzie kodu pokazano, jak utworzyć składnik o silnej nazwie, który określa zestaw klienta, który będzie miał dostęp do typów w składniku.

// friend_assemblies_5.cpp
// compile by using: /clr /LD /link /keyfile:friend_assemblies.snk
using namespace System::Runtime::CompilerServices;
using namespace System;
// an assembly attribute, not bound to a type

[assembly:InternalsVisibleTo("friend_assemblies_6, PublicKey=00240000048000009400000006020000002400005253413100040000010001000bf45d77fd991f3bff0ef51af48a12d35699e04616f27ba561195a69ebd3449c345389dc9603d65be8cd1987bc7ea48bdda35ac7d57d3d82c666b7fc1a5b79836d139ef0ac8c4e715434211660f481612771a9f7059b9b742c3d8af00e01716ed4b872e6f1be0e94863eb5745224f0deaba5b137624d7049b6f2d87fba639fc5")];

private ref class Class1 {
public:
   void Test_Public() {
      Console::WriteLine("Class1::Test_Public");
   }
};

Zwróć uwagę, że składnik musi określić jego klucz publiczny. Zalecamy uruchomienie następujących poleceń sekwencyjnie w wierszu polecenia w celu utworzenia pary kluczy i pobrania klucza publicznego:

sn -d friend_assemblies.snk

sn -k friend_assemblies.snk

sn -i friend_assemblies.snk friend_assemblies.snk

sn -pc friend_assemblies.snk key.publickey

sn -tp key.publickey

Następny przykład kodu uzyskuje dostęp do typu prywatnego w składniku silnej nazwy.

// friend_assemblies_6.cpp
// compile by using: /clr /link /keyfile:friend_assemblies.snk
#using "friend_assemblies_5.dll" as_friend

int main() {
   Class1 ^ a = gcnew Class1;
   a->Test_Public();
}
Class1::Test_Public

Zobacz też

Component Extensions dla platform środowiska uruchomieniowego