Konsep C++ Model Data Debugger

Topik ini menjelaskan konsep dalam Model Data Debugger C++ .

Konsep dalam Model Data

Objek sintetis dalam model data secara efektif merupakan dua hal:

  • Kamus tuple kunci/nilai/metadata.
  • Serangkaian konsep (antarmuka) yang didukung oleh model data. Konsep adalah antarmuka yang diterapkan klien (dibandingkan dengan model data) untuk menyediakan serangkaian perilaku semantik yang ditentukan. Kumpulan konsep yang saat ini didukung tercantum di sini.
Antarmuka Konsep Deskripsi
IDataModelConcept Konsepnya adalah model induk. Jika model ini secara otomatis dilampirkan ke jenis asli melalui tanda tangan jenis terdaftar, metode InitializeObject akan secara otomatis dipanggil setiap kali objek baru jenis tersebut dibuat.
IStringDisplayableConcept Objek dapat dikonversi ke string untuk tujuan tampilan.
IIterableConcept Objek adalah kontainer dan dapat diulang.
IIndexableConcept Objek adalah kontainer dan dapat diindeks (diakses melalui akses acak) dalam satu atau beberapa dimensi.
IPreferredRuntimeTypeConcept Objek lebih memahami tentang jenis yang berasal darinya daripada sistem jenis yang mendasarinya mampu menyediakan dan ingin menangani konversinya sendiri dari jenis statis ke runtime.
IDynamicKeyProviderConcept Objek adalah penyedia kunci dinamis dan ingin mengambil alih semua kueri utama dari model data inti. Antarmuka ini biasanya digunakan sebagai jembatan untuk bahasa dinamis seperti JavaScript.
IDynamicConceptProviderConcept Objek adalah penyedia konsep dinamis dan ingin mengambil alih semua kueri konsep dari model data inti. Antarmuka ini biasanya digunakan sebagai jembatan untuk bahasa dinamis seperti JavaScript.

Konsep Model Data: IDataModelConcept

Objek model apa pun yang dilampirkan ke objek model lain sebagai model induk harus secara langsung mendukung konsep model data. Konsep model data memerlukan dukungan antarmuka, IDataModelConcept didefinisikan sebagai berikut.

DECLARE_INTERFACE_(IDataModelConcept, IUnknown)
{
    STDMETHOD(InitializeObject)(_In_ IModelObject* modelObject, _In_opt_ IDebugHostTypeSignature* matchingTypeSignature, _In_opt_ IDebugHostSymbolEnumerator* wildcardMatches) PURE;
    STDMETHOD(GetName)(_Out_ BSTR* modelName) PURE;
}

InitializeObject

Model data dapat didaftarkan sebagai visualizer kanonis atau sebagai ekstensi untuk jenis asli tertentu melalui metode RegisterModelForTypeSignature atau RegisterExtensionForTypeSignature manajer data. Ketika model didaftarkan melalui salah satu metode ini, model data secara otomatis dilampirkan sebagai model induk ke objek asli apa pun yang jenisnya cocok dengan tanda tangan yang diteruskan dalam pendaftaran. Pada titik di mana lampiran tersebut dibuat secara otomatis, metode InitializeObject dipanggil pada model data. Ini diteruskan objek instans, tanda tangan jenis yang menyebabkan lampiran, dan enumerator yang menghasilkan instans jenis (dalam urutan linier) yang cocok dengan kartubebas apa pun dalam tanda tangan jenis. Implementasi model data dapat menggunakan panggilan metode ini untuk menginisialisasi cache apa pun yang diperlukan.

GetName

Jika model data tertentu terdaftar dengan nama default melalui metode RegisterNamedModel, antarmuka IDataModelConcept model data terdaftar harus mengembalikan nama tersebut dari metode ini. Perhatikan bahwa sangat sah bagi model untuk didaftarkan dengan beberapa nama (default atau yang terbaik harus dikembalikan di sini). Model dapat sepenuhnya tidak disebutkan namanya (selama tidak terdaftar dengan nama). Dalam keadaan seperti itu, metode GetName harus mengembalikan E_NOTIMPL.

Konsep Yang Dapat Ditampilkan String: IStringDisplayableConcept

Objek yang ingin memberikan konversi string untuk tujuan tampilan dapat mengimplementasikan konsep yang dapat ditampilkan string melalui implementasi antarmuka IStringDisplayableConcept. Antarmuka didefinisikan sebagai berikut:

DECLARE_INTERFACE_(IStringDisplayableConcept, IUnknown)
{
    STDMETHOD(ToDisplayString)(_In_ IModelObject* contextObject, _In_opt_ IKeyStore* metadata, _Out_ BSTR* displayString) PURE;
}

ToDisplayString

Metode ToDisplayString dipanggil setiap kali klien ingin mengonversi objek menjadi string untuk ditampilkan (ke konsol, di UI, dll...). Konversi string semacam itu tidak boleh digunakan untuk dasar manipulasi terprogram tambahan. Konversi string itu sendiri mungkin sangat dipengaruhi oleh metadata yang diteruskan ke panggilan. Konversi string harus melakukan setiap upaya untuk menghormati kunci PreferredRadix dan PreferredFormat.

Konsep Berulang: IIterableConcept dan IModelIterator

Objek yang merupakan kontainer objek lain dan ingin mengekspresikan kemampuan untuk melakukan iterasi atas objek yang terkandung dapat mendukung konsep berulang dengan implementasi antarmuka IIterableConcept dan IModelIterator. Ada hubungan yang sangat penting antara dukungan konsep yang dapat diulang dan dukungan konsep yang dapat diindeks. Objek yang mendukung akses acak ke objek yang terkandung dapat mendukung konsep yang dapat diindeks selain konsep yang dapat diulang. Dalam hal ini, elemen yang diulang juga harus menghasilkan indeks default yang, ketika diteruskan ke konsep yang dapat diindeks merujuk ke objek yang sama. Kegagalan untuk memenuhi invarian ini akan mengakibatkan perilaku yang tidak terdefinisi di host debug.

IIterableConcept didefinisikan sebagai berikut:

DECLARE_INTERFACE_(IIterableConcept, IUnknown)
{
    STDMETHOD(GetDefaultIndexDimensionality)(_In_ IModelObject* contextObject, _Out_ ULONG64* dimensionality) PURE;
    STDMETHOD(GetIterator)(_In_ IModelObject* contextObject, _Out_ IModelIterator** iterator) PURE;
}

Konsep IModelIterator didefinisikan sebagai berikut:

DECLARE_INTERFACE_(IModelIterator, IUnknown)
{
   STDMETHOD(Reset)() PURE;
   STDMETHOD(GetNext)(_COM_Errorptr_ IModelObject** object, _In_ ULONG64 dimensions, _Out_writes_opt_(dimensions) IModelObject** indexers, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
}

GetDefaultIndexDimensionality IIterableConcept

Metode GetDefaultIndexDimensionality mengembalikan jumlah dimensi ke indeks default. Jika objek tidak dapat diindeks, metode ini harus mengembalikan 0 dan berhasil (S_OK). Objek apa pun yang mengembalikan nilai bukan nol dari metode ini mendeklarasikan dukungan untuk kontrak protokol yang menyatakan:

  • Objek mendukung konsep yang dapat diindeks melalui dukungan IIndexableConcept
  • Metode GetNext dari IModelIterator yang dikembalikan dari metode GetIterator dari konsep iterable akan mengembalikan indeks default unik untuk setiap elemen yang dihasilkan. Indeks tersebut akan memiliki jumlah dimensi seperti yang ditunjukkan di sini.
  • Meneruskan indeks yang dikembalikan dari metode GetNext dari IModelIterator ke metode GetAt pada konsep yang dapat diindeks (IIndexableConcept) akan merujuk ke objek yang sama dengan yang diproduksi GetNext. Nilai yang sama dikembalikan.

GetIterator IIterableConcept

Metode GetIterator pada konsep iterable mengembalikan antarmuka iterator yang dapat digunakan untuk iterasi objek. Iterator yang dikembalikan harus mengingat objek konteks yang diteruskan ke metode GetIterator. Ini tidak akan diteruskan ke metode pada iterator itu sendiri.

Reset IModelIterator

Metode Reset pada iterator yang dikembalikan dari konsep iterable akan memulihkan posisi iterator ke tempat iterator pertama kali dibuat (sebelum elemen pertama). Meskipun sangat disarankan agar iterator mendukung metode Reset, itu tidak diperlukan. Iterator dapat setara dengan iterator input C++ dan hanya memungkinkan satu lolos iterasi ke depan. Dalam kasus seperti itu, metode Reset mungkin gagal dengan E_NOTIMPL.

GetNext IModelIterator

Metode GetNext memindahkan iterator ke depan dan mengambil elemen iterasi berikutnya. Jika objek dapat diindeks selain dapat diulang dan ini ditunjukkan oleh argumen GetDefaultIndexDimensionality yang mengembalikan nilai bukan nol, metode ini dapat secara opsional mengembalikan indeks default untuk kembali ke nilai yang dihasilkan dari pengindeks. Perhatikan bahwa penelepon dapat memilih untuk meneruskan 0/nullptr dan tidak mengambil indeks apa pun. Dianggap ilegal bagi penelepon untuk meminta indeks parsial (misalnya: kurang dari angka yang dihasilkan oleh GetDefaultIndexDimensionality).

Jika iterator berhasil bergerak maju tetapi ada kesalahan dalam membaca nilai elemen yang diulang, metode dapat mengembalikan kesalahan DAN mengisi "objek" dengan objek kesalahan. Di akhir iterasi elemen yang terkandung, iterator akan mengembalikan E_BOUNDS dari metode GetNext. Setiap panggilan berikutnya (kecuali telah ada panggilan Reset yang mengintervensi) juga akan mengembalikan E_BOUNDS.

Konsep yang Dapat Diindeks: IIndexableConcept

Objek yang ingin memberikan akses acak ke sekumpulan konten dapat mendukung konsep yang dapat diindeks melalui dukungan antarmuka IIndexableConcept. Sebagian besar objek yang dapat diindeks juga akan dapat diulang melalui dukungan konsep yang dapat diulang. Namun, ini tidak diperlukan. Jika didukung, ada hubungan penting antara iterator dan pengindeks. Iterator harus mendukung GetDefaultIndexDimensionality, mengembalikan nilai bukan nol dari metode tersebut, dan mendukung kontrak yang didokumenkan di sana. Antarmuka konsep pengindeks didefinisikan sebagai berikut:

DECLARE_INTERFACE_(IIndexableConcept, IUnknown)
{
    STDMETHOD(GetDimensionality)(_In_ IModelObject* contextObject, _Out_ ULONG64* dimensionality) PURE;
    STDMETHOD(GetAt)(_In_ IModelObject* contextObject, _In_ ULONG64 indexerCount, _In_reads_(indexerCount) IModelObject** indexers, _COM_Errorptr_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
    STDMETHOD(SetAt)(_In_ IModelObject* contextObject, _In_ ULONG64 indexerCount, _In_reads_(indexerCount) IModelObject** indexers, _In_ IModelObject *value) PURE;
}

Contoh penggunaan pengindeks (dan interplay-nya dengan iterator) ditunjukkan di bawah ini. Contoh ini mengulangi konten kontainer yang dapat diindeks dan menggunakan pengindeks untuk kembali ke nilai yang baru saja dikembalikan. Meskipun operasi itu secara fungsional tidak berguna seperti yang tertulis, operasi ini menunjukkan bagaimana antarmuka ini berinteraksi. Perhatikan bahwa contoh di bawah ini tidak menangani kegagalan alokasi memori. Ini mengasumsikan pelemparan baru (yang mungkin merupakan asumsi yang buruk tergantung pada lingkungan di mana kode ada -- metode COM dari model data tidak dapat memiliki pengecualian C++ lolos):

ComPtr<IModelObject> spObject;

//
// Assume we have gotten some object in spObject that is iterable (e.g.: an object which represents a std::vector<SOMESTRUCT>)
//
ComPtr<IIterableConcept> spIterable;
ComPtr<IIndexableConcept> spIndexer;
if (SUCCEEDED(spObject->GetConcept(__uuidof(IIterableConcept), &spIterable, nullptr)) &&
    SUCCEEDED(spObject->GetConcept(__uuidof(IIndexableConcept), &spIndexable, nullptr)))
{
    ComPtr<IModelIterator> spIterator;

    //
    // Determine how many dimensions the default indexer is and allocate the requisite buffer.
    //
    ULONG64 dimensions;
    if (SUCCEEDED(spIterable->GetDefaultIndexDimensionality(spObject.Get(), &dimensions)) && dimensions > 0 &&
        SUCCEEDED(spIterable->GetIterator(spObject.Get(), &spIterator)))
    {
        std::unique_ptr<ComPtr<IModelObject>[]> spIndexers(new ComPtr<IModelObject>[dimensions]);

        //
        // We have an iterator.  Error codes have semantic meaning here.  E_BOUNDS indicates the end of iteration.  E_ABORT indicates that
        // the debugger host or application is trying to abort whatever operation is occurring.  Anything else indicates
        // some other error (e.g.: memory read failure) where the iterator MIGHT still produce values.
        //
        for(;;)
        {
            ComPtr<IModelObject> spContainedStruct;
            ComPtr<IKeyStore> spContainedMetadata;

            //
            // When we fetch the value from the iterator, it will pass back the default indicies.
            //
            HRESULT hr = spIterable->GetNext(&spContainedStruct, dimensions, reinterpret_cast<IModelObject **>(spIndexers.get()), &spContainedMetadata);
            if (hr == E_BOUNDS || hr == E_ABORT)
            {
                break;
            }

            if (FAILED(hr))
            {
                //
                // Decide how to deal with failure to fetch an element.  Note that spContainedStruct *MAY* contain an error object
                // which has detailed information about why the failure occurred (e.g.: failure to read memory at address X).
                //
            }

            //
            // Use the indexer to get back to the same value.  We already have them, so there isn't much functional point to this.  It simply
            // highlights the interplay between iterator and indexer.
            //
            ComPtr<IModelObject> spIndexedStruct;
            ComPtr<IKeyStore> spIndexedMetadata;

            if (SUCCEEDED(spIndexer->GetAt(spObject.Get(), dimensions, reinterpret_cast<IModelObject **>(spIndexers.get()), &spIndexedStruct, &spIndexedMetadata)))
            {
                //
                // spContainedStruct and spIndexedStruct refer to the same object.  They may not have interface equality.
                // spContainedMetadata and spIndexedMetadata refer to the same metadata store with the same contents.  They may not have interface equality.
                //
            }
        }
    }
}

GetDimensionality

Metode GetDimensionality mengembalikan jumlah dimensi tempat objek diindeks. Perhatikan bahwa jika objek dapat diulang dan dapat diindeks, implementasi GetDefaultIndexDimensionality harus setuju dengan implementasi GetDimensionality tentang berapa banyak dimensi yang dimiliki pengindeks.

GetAt

Metode GetAt mengambil nilai pada indeks N-dimensi tertentu dari dalam objek terindeks. Pengindeks N-dimensi di mana N adalah nilai yang dikembalikan dari GetDimensionality harus didukung. Perhatikan bahwa objek mungkin dapat diindeks di domain yang berbeda dengan jenis yang berbeda (misalnya: dapat diindeks melalui ordinal dan string). Jika indeks berada di luar rentang (atau tidak dapat diakses), metode akan mengembalikan kegagalan; namun, dalam kasus seperti itu, objek output mungkin masih diatur ke objek kesalahan.

SetAt

Metode SetAt mencoba mengatur nilai pada indeks N-dimensi tertentu dari dalam objek terindeks. Pengindeks N-dimensi di mana N adalah nilai yang dikembalikan dari GetDimensionality harus didukung. Perhatikan bahwa objek mungkin dapat diindeks di domain yang berbeda dengan jenis yang berbeda (misalnya: dapat diindeks melalui ordinal dan string). Beberapa pengindeks bersifat baca-saja. Dalam kasus seperti itu, E_NOTIMPL akan dikembalikan dari panggilan apa pun ke metode SetAt.

Konsep Jenis Runtime Pilihan: IPreferredRuntimeTypeConcept

Host debug dapat dikueri untuk melakukan upaya untuk menentukan jenis runtime nyata objek dari jenis statis yang ditemukan dalam informasi simbolis. Konversi ini mungkin didasarkan pada informasi yang sepenuhnya akurat (misalnya: C++ RTTI) atau mungkin didasarkan pada heuristik yang kuat seperti bentuk tabel fungsi virtual apa pun dalam objek. Namun, beberapa objek tidak dapat dikonversi dari jenis statis ke runtime karena tidak sesuai dengan heuristik host debug (misalnya: mereka tidak memiliki tabel RTTI atau fungsi virtual). Dalam kasus seperti itu, model data untuk objek dapat memilih untuk mengambil alih perilaku default dan menyatakan bahwa ia tahu lebih banyak tentang "jenis runtime" objek daripada host debug mampu memahami. Ini dilakukan melalui konsep jenis runtime pilihan dan dukungan antarmuka IPreferredRuntimeTypeConcept.

Antarmuka IPreferredRuntimeTypeConcept dinyatakan sebagai berikut:

DECLARE_INTERFACE_(IPreferredRuntimeTypeConcept, IUnknown)
{
    STDMETHOD(CastToPreferredRuntimeType)(_In_ IModelObject* contextObject, _COM_Errorptr_ IModelObject** object) PURE;
}

CastToPreferredRuntimeType

Metode CastToPreferredRuntimeType dipanggil setiap kali klien ingin mencoba mengonversi dari instans jenis statis ke jenis runtime instans tersebut. Jika objek yang dimaksud mendukung (melalui salah satu model induk yang terlampir) konsep jenis runtime yang disukai, metode ini akan dipanggil untuk melakukan konversi. Metode ini dapat mengembalikan objek asli (tidak ada konversi atau tidak dapat dianalisis), mengembalikan instans baru dari jenis runtime, gagal karena alasan non-semantik (misalnya: kehabisan memori), atau mengembalikan E_NOT_SET. Kode kesalahan E_NOT_SET adalah kode kesalahan yang sangat khusus yang menunjukkan pada model data bahwa implementasi tidak ingin mengambil alih perilaku default dan bahwa model data harus kembali ke analisis apa pun yang dilakukan oleh host debug (misalnya: analisis RTTI, pemeriksaan bentuk tabel fungsi virtual, dll...)

Konsep Penyedia Dinamis: IDynamicKeyProviderConcept dan IDynamicConceptProviderConcept

Meskipun model data itu sendiri biasanya menangani manajemen kunci dan konsep untuk objek, ada kalanya gagasan itu kurang dari ideal. Secara khusus, ketika klien ingin membuat jembatan antara model data dan sesuatu yang benar-benar dinamis (misalnya: JavaScript), mungkin berharga untuk mengambil alih manajemen kunci dan konsep dari implementasi dalam model data. Karena model data inti adalah satu-satunya implementasi IModelObject, ini malah dilakukan melalui kombinasi dua konsep: konsep penyedia kunci dinamis dan konsep penyedia konsep dinamis. Meskipun akan menjadi tipikal untuk menerapkan keduanya atau tidak sama sekali, tidak ada persyaratan untuk itu.

Jika keduanya diimplementasikan, konsep penyedia kunci dinamis harus ditambahkan sebelum konsep penyedia konsep dinamis. Kedua konsep ini istimewa. Mereka secara efektif membalik sakelar pada objek yang mengubahnya dari "dikelola secara statis" menjadi "dikelola secara dinamis". Konsep-konsep ini hanya dapat diatur jika tidak ada kunci/konsep yang dikelola oleh model data pada objek . Setelah konsep ini ditambahkan ke objek, tindakan melakukan ini tidak dapat dibatalkan.

Ada perbedaan semantik tambahan sekeliling ekstensibilitas antara IModelObject yang merupakan penyedia konsep dinamis dan yang tidak. Konsep-konsep ini dimaksudkan untuk memungkinkan klien membuat jembatan antara model data dan sistem bahasa dinamis seperti JavaScript. Model data memiliki konsep ekstensibilitas yang agak berbeda dari sistem seperti JavaScript karena ada pohon model induk daripada rantai linier seperti rantai prototipe JavaScript. Untuk memungkinkan hubungan yang lebih baik dengan sistem tersebut, IModelObject yang merupakan penyedia konsep dinamis memiliki induk model data tunggal. Induk model data tunggal itu adalah IModelObject normal yang dapat memiliki jumlah model induk arbitrer seperti biasa untuk model data. Setiap permintaan ke penyedia konsep dinamis untuk menambahkan atau menghapus induk secara otomatis dialihkan ke induk tunggal. Dari perspektif orang luar, terlihat seolah-olah penyedia konsep dinamis memiliki rantai gaya pohon normal model induk. Pelaksana konsep penyedia konsep dinamis adalah satu-satunya objek (di luar model data inti) yang mengetahui induk tunggal perantara. Induk tunggal tersebut dapat ditautkan dengan sistem bahasa dinamis untuk menyediakan penghubung (misalnya: ditempatkan ke dalam rantai prototipe JavaScript).

Konsep penyedia kunci dinamis didefinisikan sebagai berikut:

DECLARE_INTERFACE_(IDynamicKeyProviderConcept, IUnknown)
{
    STDMETHOD(GetKey)(_In_ IModelObject *contextObject, _In_ PCWSTR key, _COM_Outptr_opt_result_maybenull_ IModelObject** keyValue, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata, _Out_opt_ bool *hasKey) PURE;
    STDMETHOD(SetKey)(_In_ IModelObject *contextObject, _In_ PCWSTR key, _In_ IModelObject *keyValue, _In_ IKeyStore *metadata) PURE;
    STDMETHOD(EnumerateKeys)(_In_ IModelObject *contextObject, _COM_Outptr_ IKeyEnumerator **ppEnumerator) PURE;
}

Konsep penyedia konsep dinamis didefinisikan sebagai berikut:

DECLARE_INTERFACE_(IDynamicConceptProviderConcept, IUnknown)
{
    STDMETHOD(GetConcept)(_In_ IModelObject *contextObject, _In_ REFIID conceptId, _COM_Outptr_result_maybenull_ IUnknown **conceptInterface, _COM_Outptr_opt_result_maybenull_ IKeyStore **conceptMetadata, _Out_ bool *hasConcept) PURE;
    STDMETHOD(SetConcept)(_In_ IModelObject *contextObject, _In_ REFIID conceptId, _In_ IUnknown *conceptInterface, _In_opt_ IKeyStore *conceptMetadata) PURE;
    STDMETHOD(NotifyParent)(_In_ IModelObject *parentModel) PURE;
    STDMETHOD(NotifyParentChange)(_In_ IModelObject *parentModel) PURE;
    STDMETHOD(NotifyDestruct)() PURE;
}

GetKey IDynamicKeyProviderConcept

Metode GetKey pada penyedia kunci dinamis sebagian besar merupakan penimpaan metode GetKey pada IModelObject. Penyedia kunci dinamis diharapkan untuk mengembalikan nilai kunci dan metadata apa pun yang terkait dengan kunci tersebut. Jika kunci tidak ada (tetapi tidak ada kesalahan lain yang terjadi), penyedia harus mengembalikan false dalam parameter hasKey dan berhasil dengan S_OK. Gagal dalam panggilan ini dianggap sebagai kegagalan untuk mengambil kunci dan akan secara eksplisit menghentikan pencarian kunci melalui rantai model induk. Mengembalikan false di hasKey dan keberhasilan akan melanjutkan pencarian kunci. Perhatikan bahwa sangat legal bagi GetKey untuk mengembalikan pengakses properti kotak sebagai kunci. Ini akan secara semantik identik dengan metode GetKey pada IModelObject yang mengembalikan pengakses properti.

SetKey IDynamicKeyProviderConcept

Metode SetKey pada penyedia kunci dinamis secara efektif merupakan penimpaan metode SetKey pada IModelObject. Ini menetapkan kunci di penyedia dinamis. Ini secara efektif membuat properti baru pada penyedia. Perhatikan bahwa penyedia yang tidak mendukung gagasan apa pun seperti pembuatan properti expando harus mengembalikan E_NOTIMPL di sini.

IDynamicKeyProviderConcept's EnumerateKeys

Metode EnumerateKeys pada penyedia kunci dinamis secara efektif merupakan penimpaan metode EnumerateKeys pada IModelObject. Ini menghitung semua kunci di penyedia dinamis. Enumerator yang dikembalikan memiliki beberapa batasan yang harus dipatuhi oleh implementasi:

  • Ini harus berperilaku sebagai panggilan ke EnumerateKeys dan bukan EnumerateKeyValues atau EnumerateKeyReferences. Ini harus mengembalikan nilai kunci yang tidak menyelesaikan aksesor properti yang mendasar (jika konsep tersebut ada di penyedia).
  • Dari perspektif penyedia kunci dinamis tunggal, adalah ilegal untuk menghitung beberapa kunci dengan nama yang sama yang merupakan kunci yang berbeda secara fisik. Ini dapat terjadi pada penyedia berbeda yang dilampirkan melalui rantai model induk, tetapi tidak dapat terjadi dari perspektif penyedia tunggal.

GetConcept IDynamicConceptProviderConcept

Metode GetConcept pada penyedia konsep dinamis secara efektif merupakan penimpaan metode GetConcept pada IModelObject. Penyedia konsep dinamis harus mengembalikan antarmuka untuk konsep yang dikueri jika ada serta metadata apa pun yang terkait dengan konsep tersebut. Jika konsep tidak ada pada penyedia, yang harus ditunjukkan melalui nilai salah yang dikembalikan dalam argumen hasConcept dan pengembalian yang berhasil. Kegagalan metode ini adalah kegagalan untuk mengambil konsep dan akan secara eksplisit menghentikan pencarian konsep. Mengembalikan false untuk hasConcept dan kode yang berhasil akan melanjutkan pencarian konsep melalui pohon model induk.

SetConcept IDynamicConceptProviderConcept

Metode SetConcept pada penyedia konsep dinamis secara efektif merupakan penimpaan metode SetConcept pada IModelObject. Penyedia dinamis akan menetapkan konsep. Ini dapat membuat objek dapat diulang, dapat diindeks, string dapat dikonversi, dll... Perhatikan bahwa penyedia yang tidak mengizinkan pembuatan konsep di dalamnya harus mengembalikan E_NOPTIMPL di sini.

NotifyParent IDynamicConceptProviderConcept

Panggilan NotifyParent pada penyedia konsep dinamis digunakan oleh model data inti untuk memberi tahu penyedia dinamis model induk tunggal yang dibuat untuk memungkinkan menjembatani paradigma "beberapa model induk" dari model data ke bahasa yang lebih dinamis. Setiap manipulasi model induk tunggal tersebut akan menyebabkan pemberitahuan lebih lanjut kepada penyedia dinamis. Perhatikan bahwa panggilan balik ini dilakukan segera setelah penugasan konsep penyedia konsep dinamis.

NotifyParentChange IDynamicConceptProviderConcept

Metode NotifyParent pada penyedia konsep dinamis adalah panggilan balik yang dibuat oleh model data inti ketika manipulasi statis dari model induk tunggal objek dibuat. Untuk model induk tertentu yang ditambahkan, metode ini akan dipanggil pertama kali ketika model induk ditambahkan dan kedua kalinya jika/ketika model induk tersebut dihapus.

NotifyDestruct IDynamicConceptProviderConcept

Metode NotifyDestruct pada penyedia konsep dinamis adalah panggilan balik yang dibuat oleh model data inti pada awal penghancuran objek yang merupakan penyedia konsep dinamis. Ini memberikan peluang pembersihan tambahan kepada klien yang membutuhkannya.

--

Lihat juga

Topik ini adalah bagian dari seri yang menjelaskan antarmuka yang dapat diakses dari C++, cara menggunakannya untuk membangun ekstensi debugger berbasis C++, dan cara menggunakan konstruksi model data lainnya (misalnya: JavaScript atau NatVis) dari ekstensi model data C++.

Gambaran Umum Model Data Debugger C++

Antarmuka C++ Model Data Debugger

Objek C++ Model Data Debugger

Model Data Debugger C++ Antarmuka Tambahan

Konsep C++ Model Data Debugger

Pembuatan Skrip C++ Model Data Debugger