Ensamblados de confianza (C++)

En el caso de los entornos de ejecución aplicables, la característica de lenguaje de ensamblados de confianza hace que los tipos que se encuentran en el ámbito del espacio de nombres o el ámbito global de un componente de ensamblado sean accesibles para uno o varios ensamblados de cliente o .netmodules.

Todos los runtimes

Observaciones

(Esta característica del lenguaje no se admite en todos los entornos de ejecución).

Windows en tiempo de ejecución

Observaciones

(Esta característica del lenguaje no se admite en Windows Runtime).

Requisitos

Opción del compilador: /ZW

Common Language Runtime

Observaciones

Para que los tipos en el ámbito del espacio de nombres o el ámbito global de un componente de ensamblado sean accesibles para un ensamblado de cliente o .netmodule

  1. En el componente, especifique un atributo InternalsVisibleToAttribute de ensamblado y pase el nombre del ensamblado de cliente o .netmodule que tendrá acceso a los tipos en el ámbito del espacio de nombres o el ámbito global del componente. Puede especificar varios ensamblados de cliente o .netmodules especificando atributos adicionales.

  2. En el ensamblado de cliente o .netmodule, cuando se hace referencia al ensamblado de componente mediante #using, pase el atributo as_friend. Si especifica el atributo as_friend para un ensamblado que no especifica InternalsVisibleToAttribute, se producirá una excepción en el entorno de ejecución si intenta acceder a un tipo en el ámbito del espacio de nombres o en el ámbito global del componente.

Se producirá un error de compilación si el ensamblado que contiene el atributo InternalsVisibleToAttribute no tiene un nombre seguro, pero sí el ensamblado de cliente que usa el atributo as_friend.

Aunque se pueden conocer los tipos en el ámbito del espacio de nombres y el ámbito global de un ensamblado de cliente o .netmodule, la accesibilidad de los miembros sigue en vigor. Por ejemplo, no puede acceder a un miembro privado.

Se debe conceder explícitamente acceso a todos los tipos de un ensamblado. Por ejemplo, el ensamblado C no tiene acceso a todos los tipos del ensamblado A si el ensamblado C hace referencia al ensamblado B y el ensamblado B tiene acceso a todos los tipos del ensamblado A.

Para obtener información sobre cómo firmar (es decir, cómo asignar un nombre seguro a un ensamblado creado mediante el compilador de Microsoft C++), vea Ensamblados de nombre seguro (Firma de ensamblados) (C++/CLI).

Como alternativa al uso de la característica de ensamblados de confianza, puede usar StrongNameIdentityPermission para restringir el acceso a tipos individuales.

Requisitos

Opción del compilador: /clr

Ejemplos

En el ejemplo de código siguiente se define un componente que especifica un ensamblado de cliente que tiene acceso a los tipos del componente.

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

En el ejemplo de código siguiente se obtiene acceso a un tipo privado del componente.

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

En el ejemplo de código siguiente se define un componente, pero no se especifica un ensamblado de cliente que tendrá acceso a los tipos del componente.

Observe que el componente está vinculado mediante /opt:noref. Esto garantiza que los tipos privados se emiten en los metadatos del componente, lo cual no es necesario cuando el atributo InternalsVisibleTo está presente. Para obtener más información, consulte el artículo /OPT (Optimizaciones).

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

En el ejemplo de código siguiente se define un cliente que intenta acceder a un tipo privado en un componente que no proporciona acceso a sus tipos privados. Debido al comportamiento del entorno de ejecución, si desea detectar la excepción, debe intentar acceder a un tipo privado en una función auxiliar.

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

En el ejemplo de código siguiente se muestra cómo crear un componente de nombre seguro que especifica un ensamblado de cliente que tendrá acceso a los tipos del componente.

// 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 el componente debe especificar su clave pública. Se recomienda ejecutar los siguientes comandos secuencialmente en un símbolo del sistema para crear un par de claves y obtener la clave pública:

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

En el ejemplo de código siguiente se obtiene acceso a un tipo privado en el componente de nombre seguro.

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

Consulte también

Extensiones de componentes para plataformas de tiempo de ejecución