QueryInterface: Menavigasi dalam Objek

Setelah Anda memiliki penunjuk awal ke antarmuka pada objek, COM memiliki mekanisme yang sangat sederhana untuk mengetahui apakah objek mendukung antarmuka spesifik lainnya dan, jika demikian, untuk mendapatkan penunjuk ke dalamnya. (Untuk informasi tentang mendapatkan penunjuk awal ke antarmuka pada objek, lihat Mendapatkan Pointer ke Objek.) Mekanisme ini adalah metode QueryInterface dari antarmuka IUnknown. Jika objek mendukung antarmuka yang diminta, metode harus mengembalikan penunjuk ke antarmuka tersebut. Ini memungkinkan objek untuk menavigasi secara bebas melalui antarmuka yang didukung objek. QueryInterface memisahkan permintaan "Apakah Anda mendukung kontrak tertentu?" dari penggunaan kontrak tersebut dengan performa tinggi setelah negosiasi berhasil.

Ketika klien awalnya mendapatkan akses ke objek, klien tersebut akan menerima, minimal, penunjuk antarmuka IUnknown (antarmuka paling mendasar) di mana ia dapat mengontrol masa pakai objek—dengan memberi tahu objek ketika dilakukan menggunakan objek —dan memanggil QueryInterface. Klien diprogram untuk meminta setiap objek yang dikelolanya untuk melakukan beberapa operasi, tetapi antarmuka IUnknown tidak memiliki fungsi untuk operasi tersebut. Sebaliknya, operasi tersebut diekspresikan melalui antarmuka lain. Klien dengan demikian diprogram untuk bernegosiasi dengan objek untuk antarmuka tersebut. Secara khusus, klien akan memanggil QueryInterface untuk meminta objek untuk antarmuka tempat klien dapat memanggil operasi yang diinginkan.

Karena objek menerapkan QueryInterface, objek memiliki kemampuan untuk menerima atau menolak permintaan. Jika objek menerima permintaan klien, QueryInterface mengembalikan pointer baru ke antarmuka yang diminta ke klien. Melalui penunjuk antarmuka tersebut, klien memiliki akses ke metode antarmuka tersebut. Jika, di sisi lain, objek menolak permintaan klien, QueryInterface mengembalikan penunjuk null—kesalahan—dan klien tidak memiliki pointer untuk memanggil fungsi yang diinginkan. Dalam hal ini, klien harus berurusan dengan baik dengan kemungkinan itu. Misalnya, klien memiliki pointer untuk antarmuka A pada objek dan meminta antarmuka B dan C. Misalkan juga bahwa objek mendukung antarmuka B tetapi tidak mendukung antarmuka C. Hasilnya adalah bahwa objek mengembalikan pointer ke B dan melaporkan bahwa C tidak didukung.

Poin kunci adalah bahwa ketika objek menolak panggilan ke QueryInterface, tidak mungkin bagi klien untuk meminta objek untuk melakukan operasi yang dinyatakan melalui antarmuka yang diminta. Klien harus memiliki penunjuk antarmuka untuk memanggil metode dalam antarmuka tersebut. Jika objek menolak untuk memberikan penunjuk yang diminta, klien harus siap untuk melakukannya tanpa, baik dengan tidak melakukan apa pun yang dimaksudkan untuk dilakukan dengan objek tersebut atau dengan mencoba untuk kembali ke antarmuka lain, mungkin kurang kuat. Fitur fungsionalitas COM ini berfungsi dengan baik dibandingkan dengan sistem berorientasi objek lainnya di mana Anda tidak dapat mengetahui apakah fungsi akan berfungsi sampai Anda memanggil fungsi tersebut, dan bahkan kemudian, menangani kegagalan tidak pasti. QueryInterface menyediakan cara yang andal dan konsisten untuk mengetahui apakah objek mendukung antarmuka sebelum mencoba memanggil metodenya.

Metode QueryInterface juga menyediakan cara yang kuat dan andal bagi objek untuk menunjukkan bahwa itu tidak mendukung kontrak tertentu. Artinya, jika dalam panggilan ke QueryInterface seseorang menanyakan objek "lama" apakah mendukung antarmuka "baru" (satu, misalnya, yang ditemukan setelah objek lama dikirim), objek lama akan andal, tanpa menyebabkan crash, menjawab "tidak." Teknologi yang mendukung ini adalah algoritma tempat IID dialokasikan. Meskipun ini mungkin tampak seperti titik kecil, sangat penting untuk arsitektur keseluruhan sistem, dan kemampuan untuk menanyakan elemen warisan tentang fungsionalitas baru adalah, yang mengejutkan, fitur yang tidak ada di sebagian besar arsitektur objek lainnya.

Menggunakan dan Menerapkan IUnknown