Friend 어셈블리(C++)
해당 런타임에는 friend 어셈블리 언어 기능을 하나 이상의 클라이언트 어셈블리에 액세스할 수 있는 어셈블리 컴포넌트를 전역 범위 또는 네임 스페이스 범위에 있는 형식의 수 있습니다 또는.netmodule입니다.
모든 런타임
설명
(이 언어 기능에 모든 런타임이 지원 되지 않습니다.)
Windows 런타임
설명
(이 언어 기능에서 지원 되는 Windows 런타임.)
요구 사항
컴파일러 옵션:/ZW
공용 언어 런타임
설명
형식이 전역 범위 또는 네임 스페이스 범위에서 어셈블리 컴포넌트 클라이언트 어셈블리에 액세스할 수 있도록 하거나.링크할 수 없습니다.
어셈블리 특성을 지정 하는 구성 요소에서 InternalsVisibleToAttribute, 및 클라이언트 어셈블리의 이름을 전달 하거나.구성 요소의 전역 범위 또는 네임 스페이스 범위에서 형식에 액세스 하는 링커여러 클라이언트 어셈블리를 지정할 수 있습니다 또는.추가 특성을 지정 하 여 netmodule입니다.
클라이언트 어셈블리에서 또는.을 사용 하 여 구성 요소 어셈블리를 참조할 때 링커에 #using, 전달 된 as_friend 특성.지정 하는 경우는 as_friend 특성을 지정 하지 않는 어셈블리에 대 한 InternalsVisibleToAttribute, 전역 범위에서 구성 요소 또는 네임 스페이스 범위에서 형식에 액세스 하려고 하면 런타임 예외가 throw 됩니다.
어셈블리에 포함 되어 있는 경우 빌드 오류가 발생 합니다에 InternalsVisibleToAttribute 특성 되지 않은 강력한 이름은 있지만 클라이언트 어셈블리를 사용 하는 as_friend 특성이.
클라이언트 어셈블리에 형식 네임 스페이스 범위 및 전역 범위에서 알 수 있지만 또는.netmodule을 멤버 액세스 가능성을 계속 적용 됩니다.예를 들어, private 멤버에 액세스할 수 없습니다.
어셈블리의 모든 형식에 대 한 액세스를 명시적으로 부여 되어야 합니다.예를 들어, 어셈블리 C 모든 유형에 액세스 어셈블리에 어셈블리 B를 참조 하는 어셈블리 C B 어셈블리 액세스 하는 모든 형식 어셈블리 A에 있는 경우 없습니다.
외부 어셈블리 형식의 액세스 가능성을 지정 하는 방법에 대 한 내용은 형식 표시 유형.
서명 하는 방법에 대 한 내용은 — 즉, 강력한 이름을 지정 하는 방법-Visual C++ 컴파일러를 사용 하 여 빌드한 어셈블리를 참조 하십시오. 강력한 이름 어셈블리(어셈블리 서명)(C++/CLI).
Friend 어셈블리 기능을 사용 하는 대신 수 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();
}
Output
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");
}
};
다음 코드 예제에서는 전용 형식을 해당 전용 형식에 액세스할 수 없는 구성 요소에 액세스 하려고 하는 클라이언트를 정의 합니다.런타임 동작 때문에 예외를 catch 하려는 경우 도우미 함수를 사용 하는 전용 형식 액세스 하려고 합니다.
// 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");
}
}
Output
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();
}
Output
Class1::Test_Public