Дружественные сборки (C++)
Для применимых сред выполнения функция языка дружественных сборок делает типы, которые находятся в пространстве имен область или глобальных область в компоненте сборки, доступном для одной или нескольких клиентских сборок или .netmodules.
Все среды выполнения
Замечания
(Эта функция языка не поддерживается во всех средах выполнения.)
Среда выполнения Windows
Замечания
(В среде выполнения Windows эта возможность языка не поддерживается.)
Требования
Параметр компилятора: /ZW
Среда CLR
Замечания
Создание типов в пространстве имен область или глобальных область в компоненте сборки, доступном для клиентской сборки или .netmodule
В компоненте укажите атрибут InternalsVisibleToAttributeсборки и передайте имя клиентской сборки или .netmodule, которая будет получать доступ к типам в пространстве имен область или глобальных область в компоненте. Можно указать несколько клиентских сборок или .netmodules, указав дополнительные атрибуты.
При ссылке на сборку
#using
компонента при использовании клиентской сборки или .netmodule передайтеas_friend
атрибут. Если указать атрибут для сборки, которая не указанаas_friend
InternalsVisibleToAttribute
, исключение среды выполнения будет возникать, если вы пытаетесь получить доступ к типу в пространстве имен область или глобальной область в компоненте.
Ошибка сборки приведет к тому, что сборка, содержащая InternalsVisibleToAttribute атрибут, не имеет строгого имени, но клиентская сборка, использующая as_friend
атрибут.
Хотя типы в пространстве имен область и глобальных область могут быть известны клиентской сборке или .netmodule, специальные возможности элементов по-прежнему поддерживаются. Например, вы не можете получить доступ к частному члену.
Доступ ко всем типам в сборке должен быть явно предоставлен. Например, сборка C не имеет доступа ко всем типам в сборке A, если сборка C ссылается на сборку B и сборку B имеет доступ ко всем типам в сборке A.
Сведения о том, как подписать (то есть как дать строгое имя) сборке, созданной с помощью компилятора Microsoft C++, см. в разделе "Сборки строгого имени" (C++/CLI).
В качестве альтернативы использованию функции дружественных сборок можно использовать StrongNameIdentityPermission для ограничения доступа к отдельным типам.
Требования
Параметр компилятора: /clr
Примеры
В следующем примере кода определяется компонент, указывающий клиентную сборку, которая имеет доступ к типам в компоненте.
// 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");
}
};
Следующий пример кода обращается к частному типу компонента.
// 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
В следующем примере кода определяется компонент, но не указывается клиентская сборка, которая будет иметь доступ к типам в компоненте.
Обратите внимание, что компонент связан с помощью /opt:noref. Это гарантирует, что частные типы создаются в метаданных компонента, которые не требуются при наличии атрибута InternalsVisibleTo
. Дополнительные сведения см. в статье Параметр /OPT (оптимизация).
// 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");
}
};
В следующем примере кода определяется клиент, который пытается получить доступ к частному типу в компоненте, который не предоставляет доступ к его частным типам. Из-за поведения среды выполнения, если вы хотите поймать исключение, необходимо попытаться получить доступ к частному типу в вспомогательной функции.
// 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
В следующем примере кода показано, как создать компонент строгого имени, указывающий клиентную сборку, которая будет иметь доступ к типам в компоненте.
// 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");
}
};
Обратите внимание, что компонент должен указать его открытый ключ. Мы рекомендуем выполнить следующие команды последовательно в командной строке, чтобы создать пару ключей и получить открытый ключ:
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
Следующий пример кода обращается к частному типу в компоненте строгого имени.
// 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
См. также
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по