Contoh untuk Mengatasi Konflik Nama Fungsi

Pertimbangkan hal berikut:

  • IADs0 tidak mendukung Func0.
  • IADs1 mendukung Func1 dan Func0.
  • IADs2 mendukung Func2 dan Func0.

Ketiga antarmuka adalah antarmuka ganda.

IADs0 : IDispatch
{
    OtherFunc();
}

IADs1 : IDispatch
{
    Func0() 
    Func1();
}

IADs2 : IDispatch
{
    Func0()
    Func2();
}
Dim myInf1 as IADs1
 
myInf1.Func1  ' IADs1::Func1 is invoked using direct vtable access 
 
myInf1.Func2  ' IADs2::Func2 is invoked using GetIDsOfNames/Invoke

Ketahuilah bahwa meskipun IADs1 tidak mendukung Func2, klien ADSI mengenali satu IDispatch yang mendukung semua antarmuka ganda dan pengiriman dalam model. Dengan demikian, klien ADSI dapat langsung memanggil Func2 menggunakan myInf1.Func2 tanpa menyelesaikan antarmuka mana yang mendukung Func2.

myInf1.Func2

IADs1 dan IADs2 memiliki fungsi yang disebut Func0, tetapi IADs1::Func0 dipanggil langsung menggunakan akses vtable, karena kedua hal berikut berlaku untuk klien:

  • Klien memiliki penunjuk ke objek IADs1 antarmuka ganda, yang memiliki fungsi yang disebut Func0.
  • Visual Basic mendukung akses vtable langsung, dengan asumsi bahwa jenis data tersedia melalui pustaka jenis.

Dalam contoh kode berikutnya, klien memiliki penunjuk antarmuka ganda ke IAD2 alih-alih IADs1. Oleh karena itu, IADs2::Func0 dipanggil menggunakan akses vtable langsung.

Dim myInf2 as IADs2
Set myInf2 = myInf1 ' Query for pointer to IADs2 
myInf2.Func0

Sekali lagi, dalam contoh kode berikutnya, IADs1 dan IADs2 memiliki fungsi yang disebut Func0, tetapi, di sini, klien memiliki pointer ke antarmuka ganda, IADs0, yang tidak memiliki fungsi yang disebut Func0. Oleh karena itu, tidak ada akses vtable langsung yang dapat dilakukan. Sebagai gantinya, IDispatch::GetIDsOfNames dan Invoke dipanggil untuk memanggil Func0.

Dim myInfNone as IADs0
Set myInfNone = myInf1    ' The aggregated object that 
   ' supports IADs1 and IADs2.
myInfNone.Func0

Pertimbangkan dua kasus ini:

  • IADs1 dan IADs2 masing-masing diimplementasikan oleh dua komponen COM, Ext1 dan Ext2. Jika Ext1 datang sebelum Ext2 di registri, IADs1::Func0 dipanggil. Namun, jika Ext2 menjadi yang pertama dalam registri, IADs2::Func0 dipanggil.
  • Jika IADs1 dan ADs2 diimplementasikan oleh objek ekstensi yang sama, Func0 selalu dipanggil oleh iaDsExtension::P rivateGetIDsOfNames dan metode PrivateInvoke ekstensi.

Pengembang ekstensi harus menentukan cara mengatasi konflik fungsi, atau properti, dari antarmuka IDispatch ganda yang berbeda yang memiliki nama yang sama dalam ekstensi. Implementasi IADsExtension::P rivateGetIDsOfNames dan metode PrivateInvoke harus menyelesaikan konflik ini. Misalnya, jika Anda menggunakan IMyInterface1::Func1 dan IMyInterface2::Func1, di mana IMyInterface1 dan IMyInterface2 adalah antarmuka IDispatch ganda yang didukung oleh objek ekstensi yang sama. Metode PrivateGetIDsOfNames dan PrivateInvoke harus menentukan Func1 mana yang harus selalu dipanggil.

Hal yang sama berlaku untuk DISPID yang bertentangan di antarmuka ganda atau IDispatch yang berbeda.

Misalnya, DISPID IMyInterface1::Y adalah 2 dalam file imyinterface1.odl, atau imyinterface1.idl. DISPID dari IMyInterface2::X juga 2 di iMyInterface2.odl. IADsExtension::P rivateGetIDsOfNames harus mengembalikan DISPID unik, dalam ekstensi itu sendiri, untuk masing-masing, alih-alih mengembalikan DISPID yang sama untuk keduanya.

ADSI menyelesaikan masalah pertama dengan tidak mendukung beberapa antarmuka dengan fungsi atau nama properti yang bertentangan. Ini menyelesaikan masalah kedua dengan menambahkan yang unik, yang berada dalam objek ekstensi yang sama, nomor antarmuka ke bit DISPID yang tidak digunakan.