Share via


Rakitan Teman (C++)

Untuk runtime yang berlaku, fitur bahasa rakitan teman membuat jenis yang berada di cakupan namespace atau cakupan global dalam komponen rakitan yang dapat diakses oleh satu atau beberapa rakitan klien atau .netmodule.

Semua Runtime

Keterangan

(Fitur bahasa ini tidak didukung di semua runtime bahasa umum.)

Windows Runtime

Keterangan

(Fitur bahasa ini tidak didukung di Windows Runtime.)

Persyaratan

Opsi pengkompilasi: /ZW

Runtime Bahasa Umum

Keterangan

Untuk membuat jenis pada cakupan namespace layanan atau cakupan global dalam komponen perakitan yang dapat diakses oleh rakitan klien atau .netmodule

  1. Dalam komponen, tentukan atribut InternalsVisibleToAttributeassembly , dan berikan nama rakitan klien atau .netmodule yang akan mengakses jenis pada cakupan namespace layanan atau cakupan global 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, berikan as_friend atribut . Jika Anda menentukan as_friend atribut untuk rakitan yang tidak menentukan InternalsVisibleToAttribute, pengecualian runtime akan dilemparkan jika Anda mencoba mengakses jenis pada cakupan namespace layanan atau cakupan global dalam komponen.

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

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 rakitan teman, Anda dapat menggunakan StrongNameIdentityPermission untuk membatasi akses ke jenis individual.

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 privat dipancarkan dalam metadata komponen, yang tidak diperlukan saat InternalsVisibleTo atribut 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 jenis privat dalam komponen yang tidak memberikan akses ke jenis privatnya. Karena perilaku runtime, jika Anda ingin menangkap pengecualian, Anda harus mencoba mengakses jenis privat dalam fungsi pembantu.

// 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 berikutnya mengakses jenis privat dalam komponen nama yang kuat.

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

Baca juga

Ekstensi Komponen untuk Platform Runtime