Friend-Assemblys (C++)

Für anwendbare Laufzeiten erstellt das Feature "Friend Assemblies Language" Typen, die sich im Namespacebereich oder globalen Bereich in einer Assemblykomponente befinden, auf die mindestens eine Clientassembly oder .netmodule zugegriffen werden kann.

Alle Laufzeiten

Anmerkungen

(Dieses Sprachfeature wird in allen Laufzeiten nicht unterstützt.)

Windows-Runtime

Anmerkungen

(Dieses Sprachfeature wird in der Windows-Runtime nicht unterstützt.)

Anforderungen

Compileroption: /ZW

Übersicht: Common Language Runtime (CLR)

Anmerkungen

So erstellen Sie Typen im Namespacebereich oder globalen Bereich in einer Assemblykomponente, auf die für eine Clientassembly oder .netmodule zugegriffen werden kann

  1. Geben Sie in der Komponente ein Assembly-Attribut InternalsVisibleToAttributean, und übergeben Sie den Namen der Clientassembly oder .netmodule, die auf Typen im Namespacebereich oder globalen Bereich in der Komponente zugreifen. Sie können mehrere Clientassemblys oder .netmodule angeben, indem Sie zusätzliche Attribute angeben.

  2. Übergeben Sie in der Clientassembly oder .netmodule, wenn Sie mithilfe #usingder Verwendung auf die Komponentenassembly verweisen, das as_friend Attribut. Wenn Sie das as_friend Attribut für eine Assembly angeben, die nicht angegeben InternalsVisibleToAttributewird, wird eine Laufzeit ausnahme ausgelöst, wenn Sie versuchen, auf einen Typ im Namespacebereich oder globalen Bereich in der Komponente zuzugreifen.

Ein Buildfehler führt dazu, wenn die Assembly, die das InternalsVisibleToAttribute Attribut enthält, keinen starken Namen hat, aber die Clientassembly, die das as_friend Attribut verwendet.

Obwohl Typen im Namespacebereich und globalen Bereich einer Clientassembly oder .netmodule bekannt sein können, ist die Barrierefreiheit von Membern weiterhin wirksam. Sie können beispielsweise nicht auf ein privates Mitglied zugreifen.

Der Zugriff auf alle Typen in einer Assembly muss explizit gewährt werden. Assembly C hat beispielsweise keinen Zugriff auf alle Typen in Assembly A, wenn Assembly C auf Assembly B und Assembly B Zugriff auf alle Typen in Assembly A hat.

Informationen zum Signieren – d. h. zum Zuweisen eines starken Namens – einer Assembly, die mithilfe des Microsoft C++-Compilers erstellt wird, finden Sie unter "Assemblysignierung mit starkem Namen" (C++/CLI).

Alternativ zur Verwendung der Funktion "Friend Assemblies" können StrongNameIdentityPermission Sie den Zugriff auf einzelne Typen einschränken.

Anforderungen

Compileroption: /clr

Beispiele

Im folgenden Codebeispiel wird eine Komponente definiert, die eine Clientassembly angibt, die Zugriff auf die Typen in der Komponente hat.

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

Im nächsten Codebeispiel wird auf einen privaten Typ in der Komponente zugegriffen.

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

Im nächsten Codebeispiel wird eine Komponente definiert, aber keine Clientassembly angegeben, die Zugriff auf die Typen in der Komponente hat.

Beachten Sie, dass die Komponente mithilfe von /opt:noref verknüpft ist. Dadurch wird sichergestellt, dass private Typen in den Metadaten der Komponente ausgegeben werden, was nicht erforderlich ist, wenn das InternalsVisibleTo Attribut vorhanden ist. Weitere Informationen finden Sie unter /OPT (Optimierungen).

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

Im folgenden Codebeispiel wird ein Client definiert, der versucht, auf einen privaten Typ in einer Komponente zuzugreifen, die keinen Zugriff auf seine privaten Typen ermöglicht. Aufgrund des Verhaltens der Laufzeit müssen Sie versuchen, auf einen privaten Typ in einer Hilfsfunktion zuzugreifen, wenn Sie die Ausnahme abfangen möchten.

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

Das nächste Codebeispiel zeigt, wie Sie eine Komponente mit starkem Namen erstellen, die eine Clientassembly angibt, die Zugriff auf die Typen in der Komponente hat.

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

Beachten Sie, dass die Komponente ihren öffentlichen Schlüssel angeben muss. Es wird empfohlen, die folgenden Befehle sequenziell an einer Eingabeaufforderung auszuführen, um ein Schlüsselpaar zu erstellen und den öffentlichen Schlüssel abzurufen:

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

Im nächsten Codebeispiel wird auf einen privaten Typ in der Komponente mit starkem Namen zugegriffen.

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

Siehe auch

Komponentenerweiterungen für Laufzeitplattformen