フレンド アセンブリ (C++)Friend Assemblies (C++)

適用可能なランタイムは、フレンド アセンブリ言語機能により、名前空間スコープ、または 1 つまたは複数のクライアント アセンブリまたは .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.)

Windows ランタイムWindows Runtime

解説Remarks

(この言語機能は Windows ランタイムでないサポート)。(This language feature is not supported in the Windows Runtime.)

必要条件Requirements

コンパイラ オプション: /ZWCompiler option: /ZW

共通言語ランタイムCommon Language Runtime

解説Remarks

アセンブリ コンポーネントの名前空間のスコープまたはグローバル スコープにある型にクライアント アセンブリ、または .netmodule にアクセスできるようにするにはTo 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 がアクセスできないすべての種類にアセンブリ A でアセンブリ C がアセンブリ B を参照し、アセンブリ 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