Bagikan melalui


Friend Assemblies (C++)

Untuk runtime yang berlaku, fitur bahasa rakitan teman memungkinkan tipe-tipe yang berada di cakupan namespace atau cakupan global dalam komponen rakitan dapat diakses oleh satu atau lebih rakitan klien atau .netmodules.

Semua Runtime

Keterangan

(Fitur ini tidak didukung di semua runtime.)

Windows Runtime

Keterangan

(Fitur bahasa ini tidak didukung di Windows Runtime.)

Persyaratan

Opsi pengkompilasi: /ZW

Common Language Runtime (CLR)

Keterangan

Untuk membuat tipe pada cakupan namespace atau cakupan global dalam komponen rakitan dapat diakses oleh assembly klien atau .netmodule.

  1. Dalam komponen, tentukan atribut InternalsVisibleToAttributeassembly, dan berikan nama assembly klien atau .netmodule yang akan mengakses tipe pada cakupan namespace atau cakupan global di dalam komponen. Anda dapat menentukan beberapa rakitan klien atau .netmodules dengan menentukan atribut tambahan.

  2. Di rakitan klien atau .netmodule, saat Anda mereferensikan perakitan komponen dengan menggunakan #using, gunakan atribut as_friend. Jika Anda menentukan atribut as_friend untuk assembly yang tidak menentukan InternalsVisibleToAttribute, pengecualian runtime akan dilemparkan jika Anda mencoba mengakses tipe pada cakupan namespace atau cakupan global dalam komponen.

Kesalahan build akan terjadi jika rakitan yang berisi atribut InternalsVisibleToAttribute tidak memiliki nama yang kuat, tetapi rakitan klien yang menggunakan atribut as_friend memilikinya.

Meskipun jenis pada cakupan namespace dan cakupan global dapat diketahui oleh rakitan klien atau .netmodule, aksesibilitas anggota masih berlaku. Misalnya, Anda tidak dapat mengakses anggota privat.

Akses ke semua jenis dalam rakitan harus diberikan secara eksplisit. Misalnya, assembly C tidak memiliki akses ke semua jenis dalam assembly A jika assembly C mereferensikan assembly B dan assembly B memiliki akses ke semua jenis di assembly A.

Untuk informasi tentang cara menandatangani—yaitu, cara memberikan nama yang kuat—rakitan yang dibuat dengan menggunakan pengkompilasi Microsoft C++, lihat Rakitan Nama Kuat (Penandatanganan Rakitan) (C++/CLI).

Sebagai alternatif untuk menggunakan fitur friend assembly, Anda dapat menggunakan StrongNameIdentityPermission untuk membatasi akses ke tipe individu.

Persyaratan

Opsi pengkompilasi: /clr

Contoh

Contoh kode berikut mendefinisikan komponen yang menentukan rakitan klien yang memiliki akses ke jenis dalam komponen.

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

Contoh kode berikutnya mengakses jenis privat dalam komponen.

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

Contoh kode berikutnya mendefinisikan komponen tetapi tidak menentukan rakitan klien yang akan memiliki akses ke jenis dalam komponen.

Perhatikan bahwa komponen ditautkan dengan menggunakan /opt:noref. Ini memastikan bahwa jenis pribadi dihasilkan dalam metadata komponen, yang tidak diperlukan saat atribut InternalsVisibleTo ada. Untuk informasi selengkapnya, lihat /OPT (Pengoptimalan).

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

Contoh kode berikut mendefinisikan klien yang mencoba mengakses tipe privat dalam komponen yang tidak mengizinkan akses ke tipe privat tersebut. Karena perilaku lingkungan eksekusi, jika Anda ingin menangkap pengecualian yang terjadi, Anda harus mencoba mengakses tipe privat dalam fungsi bantu.

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

Contoh kode berikutnya menunjukkan cara membuat komponen nama kuat yang menentukan rakitan klien yang akan memiliki akses ke jenis dalam komponen.

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

Perhatikan bahwa komponen harus menentukan kunci publiknya. Kami menyarankan agar Anda menjalankan perintah berikut secara berurutan pada prompt perintah untuk membuat pasangan kunci dan mendapatkan kunci publik:

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

Contoh kode berikut mengakses "private type" dalam "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

Lihat juga

Ekstensi Komponen untuk Platform Runtime