Дружественные сборки (C++)Friend Assemblies (C++)

Для применимых сред выполнения функция языка дружественных сборок делает типы, находящиеся в области видимости пространства имен или глобальной области в компоненте сборки, доступными для одной или нескольких клиентских сборок или NETMODULE.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.

Все среды выполненияAll Runtimes

ЗамечанияRemarks

(Эта функция языка не поддерживается во всех средах выполнения.)(This language feature is not supported in all runtimes.)

Среда выполнения WindowsWindows Runtime

ЗамечанияRemarks

(В среде выполнения Windows эта возможность языка не поддерживается.)(This language feature is not supported in the Windows Runtime.)

ТребованияRequirements

Параметр компилятора: /ZWCompiler option: /ZW

Среда CLRCommon Language Runtime

ЗамечанияRemarks

Создание типов в области видимости пространства имен или глобальной области в компоненте сборки, доступном для клиентской сборки или. netmoduleTo make types at namespace scope or global scope in an assembly component accessible to a client assembly or .netmodule

  1. В компоненте укажите атрибут сборки InternalsVisibleToAttribute и передайте имя клиентской сборки или NETMODULE, который будет обращаться к типам в области пространства имен или глобальной области в компоненте.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. Можно указать несколько клиентских сборок или NETMODULE, указав дополнительные атрибуты.You can specify multiple client assemblies or .netmodules by specifying additional attributes.

  2. В клиентской сборке или NETMODULE при ссылке на сборку компонента с помощью #using следует передать as_friend атрибут.In the client assembly or .netmodule, when you reference the component assembly by using #using, pass the as_friend attribute. Если указать as_friend атрибут для сборки, которая не указана, при InternalsVisibleToAttribute попытке доступа к типу в области пространства имен или глобальной области в компоненте будет выдано исключение времени выполнения.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.

Ошибка сборки возникает, если сборка, содержащая InternalsVisibleToAttribute атрибут, не имеет строгого имени, а Клиентская сборка, использующая атрибут, имеет значение as_friend .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.

Хотя типы в области видимости пространства имен и глобальной области могут быть известны клиентской сборке или NETMODULE, доступность членов по-прежнему действует.Although types at namespace scope and global scope can be known to a client assembly or .netmodule, member accessibility is still in effect. Например, нельзя получить доступ к закрытому члену.For example, you cannot access a private member.

Доступ ко всем типам в сборке должен быть явно предоставлен.Access to all types in an assembly must be explicitly granted. Например, сборка C не имеет доступа ко всем типам в сборке а, если сборка C ссылается на сборку B, а сборка б имеет доступ ко всем типам в сборке 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.

Сведения о том, как присвоить строгое имя сборки (сборке, построенной с помощью компилятора Microsoft C++), см. в разделе сборки со строгими именами (подписывание сборок) (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).

В качестве альтернативы использованию функции дружественных сборок можно использовать StrongNameIdentityPermission для ограничения доступа к отдельным типам.As an alternative to using the friend assemblies feature, you can use StrongNameIdentityPermission to restrict access to individual types.

ТребованияRequirements

Параметр компилятора: /clrCompiler option: /clr

ПримерыExamples

В следующем примере кода определяется компонент, указывающий клиентскую сборку, имеющую доступ к типам в компоненте.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");
   }
};

Следующий пример кода обращается к закрытому типу в компоненте.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

В следующем примере кода определяется компонент, но не указывается Клиентская сборка, которая будет иметь доступ к типам в компоненте.The next code example defines a component but does not specify a client assembly that will have access to the types in the component.

Обратите внимание, что компонент связан с помощью /OPT: NOREF.Notice that the component is linked by using /opt:noref. Это гарантирует, что закрытые типы будут выдаваться в метаданных компонента, что не требуется при InternalsVisibleTo наличии атрибута.This ensures that private types are emitted in the component's metadata, which is not required when the InternalsVisibleTo attribute is present. Дополнительные сведения см. в статье Параметр /OPT (оптимизация).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");
   }
};

В следующем примере кода определяется клиент, пытающийся получить доступ к закрытому типу в компоненте, который не предоставляет доступ к его закрытым типам.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. Из-за поведения среды выполнения, если необходимо перехватить исключение, необходимо попытаться получить доступ к закрытому типу в вспомогательной функции.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

В следующем примере кода показано, как создать компонент со строгим именем, указывающий клиентскую сборку, которая будет иметь доступ к типам в компоненте.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");
   }
};

Обратите внимание, что компонент должен указать его открытый ключ.Notice that the component must specify its public key. Мы рекомендуем последовательно выполнять следующие команды в командной строке, чтобы создать пару ключей и получить открытый ключ: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 key.publickeysn -tp key.publickey

Следующий пример кода обращается к закрытому типу в компоненте строгого имени.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

См. также разделSee also

Расширения компонентов для платформ среды выполненияComponent Extensions for Runtime Platforms