Freigeben über


Friend-Assemblies (C++)

Für anwendbare Laufzeiten ermöglicht das Sprachfeature Friend Assemblies den Zugriff auf Typen, die sich im Namensraum oder globalen Bereich einer Assemblykomponente befinden, durch eine oder mehrere Clientassemblies oder .netmodules.

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 machen Sie Typen auf Namensraumebene oder globaler Ebene in einer Assembly zugänglich, damit sie von einer Clientassembly oder einem .NET-Module genutzt werden können.

  1. Geben Sie in der Komponente ein Assembly-Attribut InternalsVisibleToAttribute an, und übergeben Sie den Namen der Client-Assembly oder des .NET-Moduls, das auf Typen auf Namespace-Ebene oder globaler Ebene in der Komponente zugreift. Sie können mehrere Clientassemblys oder .netmodule angeben, indem Sie zusätzliche Attribute angeben.

  2. In der Clientassembly oder dem .netmodule, wenn Sie mithilfe von #using auf die Komponentenassembly verweisen, übergeben Sie das as_friend-Attribut. Wenn Sie das as_friend-Attribut für eine Assembly angeben, ohne das Attribut InternalsVisibleToAttribute, wird eine Laufzeitausnahme ausgelöst, wenn Sie versuchen, auf einen Typ im Namensraum oder globalen Bereich der Komponente zuzugreifen.

Ein Buildfehler tritt auf, wenn die Assembly, die das InternalsVisibleToAttribute-Attribut enthält, keinen starken Namen hat, aber die Client-Assembly, die das as_friend-Attribut verwendet, schon.

Obwohl Typen im Namespace-Bereich und im globalen Bereich einer Client-Assembly oder einem .NET-Modul bekannt sein können, bleibt die Zugänglichkeit von Membern dennoch 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 verweist 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).

Als Alternative zur Verwendung der Funktion "Friend Assemblies" können Sie mit StrongNameIdentityPermission 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 einer stark benannten Komponente 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