Assemblies amigáveis (C++)Friend Assemblies (C++)

Para tempos de execução aplicáveis, o recurso de linguagem Friend Assemblies torna os tipos que estão no escopo de namespace ou escopo global em um componente de assembly acessível a um ou mais assemblies de cliente ou. netmodules.For applicable runtimes, the friend assemblies language feature makes types that are at namespace scope or global scope in an assembly component accessible to one or more client assemblies or .netmodules.

Todos os RuntimesAll Runtimes

ComentáriosRemarks

(Esse recurso de idioma não tem suporte em todos os tempos de execução.)(This language feature is not supported in all runtimes.)

Windows RuntimeWindows Runtime

ComentáriosRemarks

(Esse recurso de linguagem não é compatível com o Windows Runtime.)(This language feature is not supported in the Windows Runtime.)

RequisitosRequirements

Opção do compilador: /zwCompiler option: /ZW

Common Language RuntimeCommon Language Runtime

ComentáriosRemarks

Para tornar tipos no escopo de namespace ou escopo global em um componente de assembly acessível para um assembly de cliente ou. netmoduleTo make types at namespace scope or global scope in an assembly component accessible to a client assembly or .netmodule

  1. No componente, especifique um atributo de assembly InternalsVisibleToAttribute e passe o nome do assembly de cliente ou. netmodule que acessará os tipos no escopo de namespace ou escopo global no componente.In the component, specify an assembly attribute InternalsVisibleToAttribute, and pass the name of the client assembly or .netmodule that will access types at namespace scope or global scope in the component. Você pode especificar vários assemblies de cliente ou. netmodules especificando atributos adicionais.You can specify multiple client assemblies or .netmodules by specifying additional attributes.

  2. No assembly de cliente ou. netmodule, quando você faz referência ao assembly de componente usando #using , passe o as_friend atributo.In the client assembly or .netmodule, when you reference the component assembly by using #using, pass the as_friend attribute. Se você especificar o as_friend atributo para um assembly que não é especificado InternalsVisibleToAttribute , uma exceção de tempo de execução será gerada se você tentar acessar um tipo no escopo de namespace ou escopo global no componente.If you specify the as_friend attribute for an assembly that does not specify InternalsVisibleToAttribute, a runtime exception will be thrown if you try to access a type at namespace scope or global scope in the component.

Um erro de compilação ocorrerá se o assembly que contém o InternalsVisibleToAttribute atributo não tiver um nome forte, mas o assembly de cliente que usa o as_friend atributo.A build error will result if the assembly that contains the InternalsVisibleToAttribute attribute does not have a strong name but the client assembly that uses the as_friend attribute does.

Embora os tipos no escopo do namespace e no escopo global possam ser conhecidos por um assembly de cliente ou. netmodule, a acessibilidade do membro ainda está em vigor.Although types at namespace scope and global scope can be known to a client assembly or .netmodule, member accessibility is still in effect. Por exemplo, você não pode acessar um membro privado.For example, you cannot access a private member.

O acesso a todos os tipos em um assembly deve ser concedido explicitamente.Access to all types in an assembly must be explicitly granted. Por exemplo, o assembly C não tem acesso a todos os tipos no assembly A se o assembly C referenciar o assembly B e o assembly B tiver acesso a todos os tipos no assembly A.For example, assembly C does not have access to all types in assembly A if assembly C references assembly B and assembly B has access to all types in assembly A.

Para obter informações sobre como assinar, ou seja, como dar um nome forte para — um assembly criado usando o compilador do Microsoft C++, consulte assemblies de nome forte (assinatura de assembly) (C++/CLI).For information about how to sign—that is, how to give a strong name to—an assembly that is built by using the Microsoft C++ compiler, see Strong Name Assemblies (Assembly Signing) (C++/CLI).

Como alternativa ao uso do recurso Friend Assemblies, você pode usar o StrongNameIdentityPermission para restringir o acesso a tipos individuais.As an alternative to using the friend assemblies feature, you can use StrongNameIdentityPermission to restrict access to individual types.

RequisitosRequirements

Opção do compilador: /clrCompiler option: /clr

ExemplosExamples

O exemplo de código a seguir define um componente que especifica um assembly de cliente que tem acesso aos tipos no componente.The following code example defines a component that specifies a client assembly that has access to the types in the component.

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

O próximo exemplo de código acessa um tipo particular no componente.The next code example accesses a private type in the component.

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

O exemplo de código a seguir define um componente, mas não especifica um assembly de cliente que terá acesso aos tipos no componente.The next code example defines a component but does not specify a client assembly that will have access to the types in the component.

Observe que o componente está vinculado usando /OPT: NOREF.Notice that the component is linked by using /opt:noref. Isso garante que os tipos privados sejam emitidos nos metadados do componente, o que não é necessário quando o InternalsVisibleTo atributo está presente.This ensures that private types are emitted in the component's metadata, which is not required when the InternalsVisibleTo attribute is present. Para obter mais informações, consulte /opt (otimizations).For more information, see /OPT (Optimizations).

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

O exemplo de código a seguir define um cliente que tenta acessar um tipo particular em um componente que não dá acesso a seus tipos privados.The following code example defines a client that tries to access a private type in a component that does not give access to its private types. Devido ao comportamento do tempo de execução, se você quiser capturar a exceção, você deve tentar acessar um tipo privado em uma função auxiliar.Because of the behavior of the runtime, if you want to catch the exception, you must attempt to access a private type in a helper function.

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

O exemplo de código a seguir mostra como criar um componente de nome forte que especifica um assembly de cliente que terá acesso aos tipos no componente.The next code example shows how to create a strong-name component that specifies a client assembly that will have access to the types in the component.

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

Observe que o componente deve especificar sua chave pública.Notice that the component must specify its public key. Sugerimos que você execute os seguintes comandos sequencialmente em um prompt de comando para criar um par de chaves e obter a chave pública:We suggest that you run the following commands sequentially at a command prompt to create a key pair and get the public key:

SN-d friend_assemblies. SNKsn -d friend_assemblies.snk

SN-k friend_assemblies. SNKsn -k friend_assemblies.snk

sn-i friend_assemblies. SNK friend_assemblies. SNKsn -i friend_assemblies.snk friend_assemblies.snk

SN-PC friend_assemblies. SNK Key. PublicKeysn -pc friend_assemblies.snk key.publickey

SN-TP chave. PublicKeysn -tp key.publickey

O próximo exemplo de código acessa um tipo privado no componente de nome forte.The next code example accesses a private type in the strong-name component.

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

Veja tambémSee also

Extensões de componentes para plataformas de runtimeComponent Extensions for Runtime Platforms