Antarmuka IMarshal (objidl.h)
Memungkinkan objek COM untuk menentukan dan mengelola marshaling penunjuk antarmukanya.
Warisan
Antarmuka IMarshal mewarisi dari antarmuka IUnknown . IMarshal juga memiliki jenis anggota ini:
Metode
Antarmuka IMarshal memiliki metode ini.
IMarshal::D isconnectObject Metode IMarshal::D isconnectObject (objidl.h) melepaskan semua koneksi ke objek sebelum dimatikan. |
IMarshal::GetMarshalSizeMax Mengambil ukuran maksimum buffer yang akan diperlukan selama marshaling. |
IMarshal::GetUnmarshalClass Mengambil CLSID dari kode yang belum dibaca. |
IMarshal::MarshalInterface Metode IMarshal::MarshalInterface (objidl.h) membuat penunjuk antarmuka. |
IMarshal::ReleaseMarshalData Metode IMarshal::ReleaseMarshalData (objidl.h) menghancurkan paket data marshal. |
IMarshal::UnmarshalInterface Metode IMarshal::UnmarshalInterface (objidl.h) membatalkan nama penunjuk antarmuka. |
Keterangan
Marshaling adalah proses pengemasan data ke dalam paket untuk transmisi ke proses atau komputer yang berbeda. Unmarshaling adalah proses pemulihan data tersebut di akhir penerimaan. Dalam setiap panggilan yang diberikan, argumen metode di-marshalasikan dan tidak terhalang dalam satu arah, sementara nilai yang dikembalikan dinaungi dan tidak ternama di sisi lain.
Meskipun marshaling berlaku untuk semua jenis data, penunjuk antarmuka memerlukan penanganan khusus. Masalah mendasar adalah bagaimana kode klien yang berjalan di satu ruang alamat dapat dengan benar mendereferensikan penunjuk ke antarmuka pada objek yang berada di ruang alamat yang berbeda. Solusi COM adalah aplikasi klien untuk berkomunikasi dengan objek asli melalui objek pengganti, atau proksi, yang hidup dalam proses klien. Proksi menyimpan referensi ke antarmuka pada objek asli dan memberi klien penunjuk ke antarmuka itu sendiri. Ketika klien memanggil metode antarmuka pada objek asli, panggilannya benar-benar masuk ke proksi. Oleh karena itu, dari sudut pandang klien, semua panggilan sedang dalam proses.
Saat menerima panggilan, proksi mendeskripsikan argumen metode dan melalui beberapa cara komunikasi antarproses, seperti RPC, meneruskannya ke kode dalam proses server, yang membatalkan nama argumen dan meneruskannya ke objek asli. Marshal kode yang sama ini mengembalikan nilai untuk transmisi kembali ke proksi, yang membatalkan nama nilai dan meneruskannya ke aplikasi klien.
IMarshal menyediakan metode untuk membuat, menginisialisasi, dan mengelola proksi dalam proses klien; ini tidak menentukan bagaimana proksi harus berkomunikasi dengan objek asli. Implementasi default COM dari IMarshal menggunakan RPC. Saat Anda menerapkan antarmuka ini sendiri, Anda bebas memilih metode komunikasi antarproses apa pun yang dianggap sesuai untuk aplikasi Anda—memori bersama, bernama pipa, handel jendela, RPC—singkatnya, apa pun yang berfungsi.
Implementasi Default IMarshal
COM menggunakan implementasi internal antarmuka IMarshal sendiri untuk marshal objek apa pun yang tidak menyediakan implementasinya sendiri. COM membuat penentuan ini dengan mengkueri objek untuk IMarshal. Jika antarmuka hilang, COM default ke implementasi internalnya.Implementasi default COM dari IMarshal menggunakan proksi generik untuk setiap objek dan membuat stub dan proksi individual, karena diperlukan, untuk setiap antarmuka yang diimplementasikan pada objek . Mekanisme ini diperlukan karena COM tidak dapat mengetahui terlebih dahulu antarmuka tertentu apa yang dapat diterapkan objek tertentu. Pengembang yang tidak menggunakan marshaling default COM, memilih sebagai gantinya untuk menulis rutinitas proksi dan marshaling mereka sendiri, tahu pada waktu kompilasi semua antarmuka yang akan ditemukan pada objek mereka dan karena itu memahami dengan tepat apa kode marshaling diperlukan. COM, dalam memberikan dukungan marshaling untuk semua objek, harus melakukannya pada durasi.
Proksi antarmuka berada dalam proses klien; stub antarmuka berada di server. Bersama-sama, setiap pasangan menangani semua marshaling untuk antarmuka. Pekerjaan setiap proksi antarmuka adalah untuk argumen marshal dan nilai pengembalian yang tidak biasa dan parameter keluar yang diteruskan bolak-balik dalam panggilan berikutnya ke antarmukanya. Pekerjaan setiap potong antarmuka adalah untuk membatalkan amarshal argumen fungsi dan meneruskannya ke objek asli dan kemudian marshal nilai yang dikembalikan dan parameter keluar yang dikembalikan objek.
Proksi dan stub berkomunikasi dengan saluran RPC (panggilan prosedur jarak jauh), yang menggunakan infrastruktur RPC sistem untuk komunikasi antarproses. Saluran RPC mengimplementasikan satu antarmuka, IRpcChannelBuffer, tempat proksi antarmuka dan stub memegang pointer. Proksi dan stub memanggil antarmuka untuk mendapatkan paket marshaling, mengirim data ke rekan mereka, dan menghancurkan paket ketika mereka selesai. Potong antarmuka juga menyimpan penunjuk ke objek asli.
Untuk antarmuka tertentu, proksi dan stub keduanya diimplementasikan sebagai instans dari kelas yang sama, yang tercantum untuk setiap antarmuka dalam registri sistem di bawah label ProxyStubClsid32. Entri ini memetakan IID antarmuka ke CLSID dari proksi dan objek stub-nya. Ketika COM perlu melakukan marshal antarmuka, COM akan melihat ke dalam registri sistem untuk mendapatkan CLSID yang sesuai. Server yang diidentifikasi oleh CLSID ini mengimplementasikan proksi antarmuka dan stub antarmuka.
Paling sering, kelas yang dirujuk CLSID ini secara otomatis dihasilkan oleh alat yang inputnya adalah deskripsi tanda tangan fungsi dan semantik antarmuka tertentu, yang ditulis dalam beberapa bahasa deskripsi antarmuka. Saat menggunakan bahasa seperti itu sangat disarankan dan didorong demi akurasi, melakukannya tidak diperlukan. Proksi dan stub hanyalah komponen COM yang digunakan oleh infrastruktur RPC dan, dengan demikian, dapat ditulis dengan cara apa pun yang diinginkan, selama kontrak eksternal yang benar ditegakkan. Programmer yang merancang antarmuka baru bertanggung jawab untuk memastikan bahwa semua proksi antarmuka dan stub yang pernah ada menyetujui representasi data marshal mereka.
Saat dibuat, proksi antarmuka selalu diagregasi ke dalam proksi yang lebih besar, yang mewakili objek secara keseluruhan. Proksi objek ini juga menggabungkan objek proksi generik COM, yang dikenal sebagai manajer proksi. Manajer proksi mengimplementasikan dua antarmuka: IUnknown dan IMarshal. Semua antarmuka lain yang dapat diimplementasikan pada objek diekspos dalam proksi objeknya melalui agregasi proksi antarmuka individu. Klien yang memegang pointer ke proksi objek "percaya" ia memegang pointer ke objek aktual.
Proksi yang mewakili objek secara keseluruhan diperlukan dalam proses klien sehingga klien dapat membedakan panggilan ke antarmuka yang sama yang diterapkan pada objek yang sama sekali berbeda. Persyaratan seperti itu tidak ada dalam proses server, namun, di mana objek itu sendiri berada, karena semua tindak antarmuka hanya berkomunikasi dengan objek yang dibuat. Tidak ada koneksi lain yang dimungkinkan.
Ganjalan antarmuka, berbeda dengan proksi antarmuka, tidak diagregasi karena tidak perlu bahwa mereka muncul ke beberapa klien eksternal untuk menjadi bagian dari keseluruhan yang lebih besar. Saat tersambung, potong antarmuka diberikan penunjuk ke objek server yang harus diteruskan oleh pemanggilan metode yang diterimanya. Meskipun berguna untuk merujuk secara konseptual ke manajer stub, yang berarti apa pun potongan kode dan status dalam infrastruktur RPC sisi server yang melayani jarak jauh objek tertentu, tidak ada persyaratan langsung bahwa kode dan status mengambil bentuk tertentu yang ditentukan dengan baik.
Pertama kali klien meminta pointer ke antarmuka pada objek tertentu, COM memuat stub IClassFactory dalam proses server dan menggunakannya untuk marshal pointer pertama kembali ke klien. Dalam proses klien, COM memuat proksi generik untuk objek pabrik kelas dan memanggil implementasi IMarshal untuk membatalkan amarshal pointer pertama tersebut. COM kemudian membuat proksi antarmuka pertama dan memberinya penunjuk ke saluran RPC. Akhirnya, COM mengembalikan penunjuk IClassFactory ke klien, yang menggunakannya untuk memanggil IClassFactory::CreateInstance, meneruskannya referensi ke antarmuka.
Kembali ke proses server, COM sekarang membuat instans baru objek, bersama dengan stub untuk antarmuka yang diminta. Stub ini membantah penunjuk antarmuka kembali ke proses klien, di mana proksi objek lain dibuat, kali ini untuk objek itu sendiri. Juga dibuat adalah proksi untuk antarmuka yang diminta, pointer yang dikembalikan ke klien. Dengan panggilan berikutnya ke antarmuka lain pada objek , COM akan memuat stub antarmuka dan proksi yang sesuai sesuai kebutuhan.
Ketika proksi antarmuka baru dibuat, COM memberinya penunjuk ke implementasi IUnknown manajer proksi, yang mendelegasikan semua panggilan QueryInterface . Setiap proksi antarmuka mengimplementasikan dua antarmukanya sendiri: antarmuka yang diwakilinya dan IRpcProxyBuffer. Proksi antarmuka mengekspos antarmukanya sendiri langsung ke klien, yang dapat memperoleh penunjuknya dengan memanggil QueryInterface pada manajer proksi. Namun, hanya COM yang dapat memanggil IRpcProxyBuffer, yang digunakan untuk menyambungkan dan memutuskan koneksi proksi ke saluran RPC. Klien tidak dapat meminta proksi antarmuka untuk mendapatkan penunjuk ke antarmuka IRpcProxyBuffer .
Di sisi server, setiap stub antarmuka mengimplementasikan IRpcStubBuffer. Kode server yang bertindak sebagai manajer stub memanggil IRpcStubBuffer::Connect dan melewati stub antarmuka penunjuk IUnknown objeknya.
Ketika proksi antarmuka menerima pemanggilan metode, ia mendapatkan paket marshaling dari saluran RPC-nya melalui panggilan ke IRpcChannelBuffer::GetBuffer. Proses marshaling argumen akan menyalin data ke dalam buffer. Ketika marshaling selesai, proksi antarmuka memanggil IRpcChannelBuffer::SendReceive untuk mengirim paket marshal ke rintangan antarmuka yang sesuai. Ketika IRpcChannelBuffer::SendReceive kembali, buffer tempat argumen di-marshalasi akan digantikan oleh buffer baru yang berisi nilai kembalian yang dinaungi dari rintangan antarmuka. Proksi antarmuka membatalkan nama nilai pengembalian, memanggil IRpcChannelBuffer::FreeBuffer untuk membebaskan buffer, lalu mengembalikan nilai kembali ke pemanggil asli metode.
Ini adalah implementasi IRpcChannelBuffer::SendReceive yang benar-benar mengirim permintaan ke proses server dan yang tahu cara mengidentifikasi proses server dan, dalam proses itu, objek tempat permintaan harus dikirim. Implementasi saluran juga tahu cara meneruskan permintaan ke manajer stub yang sesuai dalam proses itu. Rintangan antarmuka membatalkan nama argumen dari buffer yang disediakan, memanggil metode yang ditunjukkan pada objek server, dan membasmi nilai yang dikembalikan kembali ke buffer baru yang dialokasikan oleh panggilan ke IRpcChannelBuffer::GetBuffer. Saluran kemudian mengirimkan paket data kembali ke proksi antarmuka, yang masih berada di tengah-tengah IRpcChannelBuffer::SendReceive, yang kembali ke proksi antarmuka.
Instans tertentu dari proksi antarmuka dapat digunakan untuk melayani lebih dari satu antarmuka, selama kondisi berikut terpenuhi:
- IID antarmuka yang terpengaruh harus dipetakan ke ProxyStubClsid yang sesuai dalam registri sistem.
- Proksi antarmuka harus mendukung panggilan ke QueryInterface dari satu antarmuka yang didukung ke antarmuka lain, seperti biasa, serta dari IUnknown dan IRpcProxyBuffer.
Pada berbagai waktu, proksi dan ganja harus mengalokasikan atau membebaskan memori. Proksi antarmuka, misalnya, perlu mengalokasikan memori untuk mengembalikan parameter ke pemanggilnya. Dalam hal ini, proksi antarmuka dan stub antarmuka hanyalah komponen COM normal, karena harus menggunakan alokator tugas standar. (Lihat CoGetMalloc.)
Persyaratan
Persyaratan | Nilai |
---|---|
Klien minimum yang didukung | Windows 2000 Professional [aplikasi desktop | Aplikasi UWP] |
Server minimum yang didukung | Windows 2000 Server [aplikasi desktop | Aplikasi UWP] |
Target Platform | Windows |
Header | objidl.h (termasuk ObjIdl.h) |