Dela via


Vänsammansättningar (C++)

För tillämpliga körningstider gör friend assemblies-språkfunktionen typer som finns på namnområdesnivå eller global nivå i en sammansättning tillgängliga för en eller flera klientsammansättningar eller .netmoduler.

Alla körningar

Anmärkningar

(Den här språkfunktionen stöds inte i alla körningsmiljöer.)

Windows Runtime

Anmärkningar

(Den här språkfunktionen stöds inte i Windows Runtime.)

Kravspecifikation

Kompilatoralternativ: /ZW

Allmänt språk-runtime

Anmärkningar

Så här gör du typer i namnområdesomfång eller globalt omfång i en sammansättningskomponent tillgängliga för en klientsammansättning eller .netmodule

  1. I komponenten anger du ett sammansättningsattribut InternalsVisibleToAttributeoch skickar namnet på klientsammansättningen eller .netmodule som kommer åt typerna i namnområdesomfånget eller det globala omfånget i komponenten. Du kan ange flera klientsammansättningar eller .netmoduler genom att ange ytterligare attribut.

  2. I klientsammansättningen eller .netmodule, när du refererar till komponentsammansättningen med hjälp av #using, skicka attributet as_friend. Om du anger as_friend attributet för en sammansättning som inte anger InternalsVisibleToAttributeutlöses ett körningsundundatag om du försöker komma åt en typ i namnområdesomfånget eller det globala omfånget i komponenten.

Ett versionsfel uppstår om sammansättningen som innehåller InternalsVisibleToAttribute attributet inte har ett starkt namn, men klientsammansättningen som använder as_friend attributet gör det.

Även om typer i namnområdesomfång och globalt omfång kan vara kända för en klientsammansättning eller .netmodule, är medlemstillgänglighet fortfarande i kraft. Du kan till exempel inte komma åt en privat medlem.

Åtkomst till alla typer i en sammansättning måste ges uttryckligen. Sammansättning C har till exempel inte åtkomst till alla typer i sammansättning A om sammansättning C refererar till sammansättning B och sammansättning B har åtkomst till alla typer i sammansättning A.

Information om hur du signerar – det vill s.v.s. hur du ger ett starkt namn till – en sammansättning som skapas med hjälp av Microsoft C++-kompilatorn finns i Strong Name Assemblies (Assembly Signing) (C++/CLI).

Som ett alternativ till att använda funktionen vänsammansättningar kan du använda StrongNameIdentityPermission för att begränsa åtkomsten till enskilda typer.

Kravspecifikation

Kompilatoralternativ: /clr

Exempel

I följande kodexempel definieras en komponent som anger en klientsammansättning som har åtkomst till typerna i komponenten.

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

I nästa kodexempel får du åtkomst till en privat typ i komponenten.

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

Nästa kodexempel definierar en komponent men anger inte en klientsammansättning som ska ha åtkomst till typerna i komponenten.

Observera att komponenten är länkad med /opt:noref. Detta säkerställer att privata typer genereras i komponentens metadata, vilket inte krävs när InternalsVisibleTo attributet finns. Mer information finns i /OPT (Optimeringar).

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

I följande kodexempel definieras en klient som försöker komma åt en privat typ i en komponent som inte ger åtkomst till sina privata typer. På grund av körmiljöns beteende måste du försöka komma åt en privat typ i en hjälpfunktion om du vill fånga undantaget.

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

I nästa kodexempel visas hur du skapar en komponent med starkt namn som anger en klientsammansättning som ska ha åtkomst till typerna i komponenten.

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

Observera att komponenten måste ange sin offentliga nyckel. Vi föreslår att du kör följande kommandon sekventiellt i en kommandotolk för att skapa ett nyckelpar och hämta den offentliga nyckeln:

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

I nästa kodexempel används en privat typ i komponenten strong-name.

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

Se även

Komponentutökningar för Körningsplattformar