Objek C++ Model Data Debugger

Topik ini menjelaskan cara menggunakan Objek C++ Model Data Debugger dan bagaimana mereka dapat memperluas kemampuan debugger.

Model Objek Debugger Inti

Salah satu hal paling mendasar namun kuat tentang model data adalah bahwa ia menstandarkan definisi apa itu objek dan bagaimana seseorang berinteraksi dengan objek. Antarmuka IModelObject merangkum gagasan objek -- apakah objek tersebut adalah bilangan bulat, nilai titik mengambang, string, beberapa jenis kompleks di ruang alamat target debugger, atau beberapa konsep debugger seperti gagasan proses atau modul.

Ada beberapa hal berbeda yang dapat disimpan di (atau dikotak ke dalam) IModelObject:

  • Nilai Intrinsik - IModelObject dapat menjadi kontainer untuk sejumlah jenis dasar: 8, 16, 32, atau bilangan bulat yang ditandatangani atau tidak ditandatangani 64 bit, boolean, string, kesalahan, atau gagasan kosong.

  • Objek Asli - IModelObject dapat mewakili jenis kompleks (sebagaimana didefinisikan oleh sistem jenis debugger) dalam ruang alamat apa pun yang ditargetkan debugger

  • Objek Sintetis - IModelObject dapat menjadi objek dinamis -- kamus jika Anda akan: kumpulan tuple kunci / nilai / metadata dan serangkaian konsep yang menentukan perilaku yang tidak hanya diwakili oleh pasangan kunci / nilai.

  • Properti - IModelObject dapat mewakili properti: sesuatu yang nilainya dapat diambil atau diubah dengan panggilan metode. Properti dalam IModelObject secara efektif adalah antarmuka IModelPropertyAccessor yang dikotak ke dalam IModelObject

  • Metode - IModelObject dapat mewakili metode: sesuatu yang dapat Anda panggil dengan sekumpulan argumen dan mendapatkan nilai yang dikembalikan. Metode dalam IModelObject secara efektif adalah antarmuka IModelMethod yang dikotak ke dalam IModelObject

Ekstensibilitas dalam model objek

IModelObject bukan objek dalam isolasi. Selain mewakili salah satu jenis objek yang ditunjukkan di atas, setiap objek memiliki gagasan tentang rantai model data induk. Rantai ini berkinerja seperti rantai prototipe JavaScript. Alih-alih rantai linier prototipe seperti yang dimiliki JavaScript, setiap objek model data menentukan rantai linier model induk. Masing-masing model induk tersebut pada gilirannya memiliki rantai linier lain dari sekumpulan orang tuanya sendiri. Intinya, setiap objek adalah agregasi kemampuan (properti, dll...) dari keduanya dan setiap objek di pohon ini. Saat properti tertentu dikueri, jika objek yang dikueri tidak mendukung properti tersebut, kueri diteruskan dalam urutan linier ke setiap induk secara bergantian. Ini menciptakan perilaku di mana pencarian properti diselesaikan oleh pencarian pohon agregat yang mengutamakan kedalaman.

Ekstensibilitas dalam model objek ini sangat sederhana mengingat gagasan ini bahwa setiap objek adalah agregat dirinya sendiri dan pohon model induk. Ekstensi dapat masuk dan menambahkan dirinya ke dalam daftar model induk untuk objek lain. Melakukan ini memperluas objek . Dengan cara ini, dimungkinkan untuk menambahkan kemampuan ke apa pun: instans tertentu dari objek atau nilai, jenis asli, konsep debugger tentang apa itu proses atau utas, atau bahkan gagasan "semua objek yang dapat diulang".

Konteks, Konteks, dan Konteks: Pointer ini , Ruang Alamat, dan Implementasi Data Privat

Ada tiga gagasan konteks yang perlu dipahami dalam konteks model objek.

Konteks: Penunjuk ini

Karena properti atau metode tertentu dapat diimplementasikan pada tingkat pohon model data apa pun, perlu implementasi metode atau properti untuk dapat mengakses objek asli (apa yang mungkin Anda sebut penunjuk ini di C++ atau objek ini di JavaScript. Objek instans tersebut diteruskan ke berbagai metode sebagai argumen pertama yang disebut konteks dalam metode yang dijelaskan.

Konteks: Ruang Alamat

Penting untuk dicatat bahwa tidak seperti model ekstensi sebelumnya di mana konteks (target, proses, utas yang Anda lihat) adalah konsep UI dengan semua API yang relatif terhadap status UI saat ini, antarmuka model data biasanya mengambil konteks ini baik secara eksplisit atau implisit sebagai antarmuka IDebugHostContext . Setiap IModelObject dalam model data membawa jenis informasi konteks ini bersama dengannya dan dapat menyebarluaskan konteks tersebut ke objek yang dikembalikannya. Ini berarti bahwa ketika Anda membaca nilai asli atau nilai kunci dari IModelObject, nilai tersebut akan membaca dari target dan memproses dari mana objek awalnya diperoleh.

Ada nilai konstanta eksplisit, USE_CURRENT_HOST_CONTEXT, yang dapat diteruskan ke metode yang mengambil argumen IDebugHostContext . Nilai ini menunjukkan bahwa konteksnya memang harus menjadi status UI debugger saat ini. Namun, gagasan ini perlu eksplisit.

Konteks: Implementasi Data Privat

Ingatlah bahwa setiap objek dalam model data sebenarnya adalah agregat instans objek dan pohon model induk yang dilampirkan. Masing-masing model induk tersebut (yang dapat ditautkan dalam rantai berbagai objek) dapat mengaitkan data implementasi privat dengan objek instans apa pun. Setiap IModelObject yang dibuat secara konseptual memiliki tabel hash yang memetakan dari model induk tertentu ke data instans privat yang ditentukan oleh antarmuka IUnknown . Ini memungkinkan model induk untuk menyimpan informasi pada setiap instans atau memiliki data arbitrer yang terkait.

Jenis konteks ini diakses melalui metode GetContextForDataModel dan SetContextForDataModel pada IModelObject.

Antarmuka Objek Debugger Inti: IModelObject


Antarmuka IModelObject didefinisikan sebagai berikut:

DECLARE_INTERFACE_(IModelObject, IUnknown)
{
    STDMETHOD(QueryInterface)(_In_ REFIID iid, _COM_Outptr_ PVOID* iface);
    STDMETHOD_(ULONG, AddRef)();
    STDMETHOD_(ULONG, Release)() PURE;
    STDMETHOD(GetContext)(_COM_Outptr_result_maybenull_ IDebugHostContext** context) PURE;
    STDMETHOD(GetKind)(_Out_ ModelObjectKind *kind) PURE;
    STDMETHOD(GetIntrinsicValue)(_Out_ VARIANT* intrinsicData);
    STDMETHOD(GetIntrinsicValueAs)(_In_ VARTYPE vt, _Out_ VARIANT* intrinsicData) PURE;
    STDMETHOD(GetKeyValue)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
    STDMETHOD(SetKeyValue)(_In_ PCWSTR key, _In_opt_ IModelObject* object) PURE;
    STDMETHOD(EnumerateKeyValues)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
    STDMETHOD(GetRawValue)(_In_ SymbolKind kind, _In_ PCWSTR name, _In_ ULONG searchFlags, _COM_Errorptr_ IModelObject** object) PURE;
    STDMETHOD(EnumerateRawValues)(_In_ SymbolKind kind, _In_ ULONG searchFlags, _COM_Outptr_ IRawEnumerator** enumerator) PURE;
    STDMETHOD(Dereference)(_COM_Errorptr_ IModelObject** object) PURE;
    STDMETHOD(TryCastToRuntimeType)(_COM_Errorptr_ IModelObject** runtimeTypedObject) PURE;
    STDMETHOD(GetConcept)(_In_ REFIID conceptId, _COM_Outptr_ IUnknown** conceptInterface, _COM_Outptr_opt_result_maybenull_ IKeyStore** conceptMetadata) PURE;
    STDMETHOD(GetLocation)(_Out_ Location* location) PURE;
    STDMETHOD(GetTypeInfo)(_Out_ IDebugHostType** type) PURE;
    STDMETHOD(GetTargetInfo)(_Out_ Location* location, _Out_ IDebugHostType** type) PURE;
    STDMETHOD(GetNumberOfParentModels)(_Out_ ULONG64* numModels) PURE;
    STDMETHOD(GetParentModel)(_In_ ULONG64 i, _COM_Outptr_ IModelObject **model, _COM_Outptr_result_maybenull_ IModelObject **contextObject) PURE;
    STDMETHOD(AddParentModel)(_In_ IModelObject* model, _In_opt_ IModelObject* contextObject, _In_ bool override) PURE;
    STDMETHOD(RemoveParentModel)(_In_ IModelObject* model) PURE;
    STDMETHOD(GetKey)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
    STDMETHOD(GetKeyReference)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** objectReference, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
    STDMETHOD(SetKey)(_In_ PCWSTR key, _In_opt_ IModelObject* object, _In_opt_ IKeyStore* metadata) PURE;
    STDMETHOD(ClearKeys)() PURE;
    STDMETHOD(EnumerateKeys)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
    STDMETHOD(EnumerateKeyReferences)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
    STDMETHOD(SetConcept)(_In_ REFIID conceptId, _In_ IUnknown* conceptInterface, _In_opt_ IKeyStore* conceptMetadata) PURE;
    STDMETHOD(ClearConcepts)() PURE;
    STDMETHOD(GetRawReference)(_In_ SymbolKind kind, _In_ PCWSTR name, _In_ ULONG searchFlags, _COM_Errorptr_ IModelObject** object) PURE;
    STDMETHOD(EnumerateRawReferences)(_In_ SymbolKind kind, _In_ ULONG searchFlags, _COM_Outptr_ IRawEnumerator** enumerator) PURE;
    STDMETHOD(SetContextForDataModel)(_In_ IModelObject* dataModelObject, _In_ IUnknown* context) PURE;
    STDMETHOD(GetContextForDataModel)(_In_ IModelObject* dataModelObject, _Out_ IUnknown** context) PURE;
    STDMETHOD(Compare)(_In_ IModelObject* other, _COM_Outptr_opt_result_maybenull_ IModelObject **ppResult) PURE;
    STDMETHOD(IsEqualTo)(_In_ IModelObject* other, _Out_ bool* equal) PURE;
}

Metode Dasar

Berikut ini adalah metode umum yang berlaku untuk semua jenis objek yang diwakili oleh IModelObject.

STDMETHOD(GetKind)(_Out_ ModelObjectKind *kind) PURE;
STDMETHOD(GetContext)(_COM_Outptr_result_maybenull_ IDebugHostContext** context) PURE;
STDMETHOD(GetIntrinsicValue)(_Out_ VARIANT* intrinsicData);
STDMETHOD(GetIntrinsicValueAs)(_In_ VARTYPE vt, _Out_ VARIANT* intrinsicData) PURE;
STDMETHOD(Compare)(_In_ IModelObject* other, _COM_Outptr_opt_result_maybenull_ IModelObject **ppResult) PURE;
STDMETHOD(IsEqualTo)(_In_ IModelObject* other, _Out_ bool* equal) PURE;
STDMETHOD(Dereference)(_COM_Errorptr_ IModelObject** object) PURE;

GetKind

Metode GetKind mengembalikan jenis objek apa yang dikotak di dalam IModelObject.

GetContext

Metode GetContext mengembalikan konteks host yang terkait dengan objek .

GetIntrinsicValue

Metode GetIntrinsicValue mengembalikan hal yang dikotak di dalam IModelObject. Metode ini hanya dapat dipanggil secara legal pada antarmuka IModelObject yang mewakili intrinsik kotak atau antarmuka tertentu yang dikotak. Ini tidak dapat dipanggil pada objek asli, tidak ada objek nilai, objek sintetis, dan objek referensi. Metode GetIntrinsicValueAs bereaksi sebanyak metode GetIntrinsicValue kecuali bahwa metode ini mengonversi nilai ke jenis varian yang ditentukan. Jika konversi tidak dapat dilakukan, metode mengembalikan kesalahan.

IsEqualTo

Metode IsEqualTo membandingkan dua objek model dan mengembalikan apakah keduanya sama dalam nilai. Untuk objek yang memiliki pengurutan, metode yang mengembalikan true ini setara dengan metode Bandingkan yang mengembalikan 0. Untuk objek yang tidak memiliki pengurutan tetapi sama, metode Bandingkan akan gagal, tetapi ini tidak akan. Arti perbandingan berbasis nilai ditentukan oleh jenis objek. Saat ini, ini hanya didefinisikan untuk jenis intrinsik dan objek kesalahan. Tidak ada konsep model data saat ini untuk kesamaan.

Dereferensi

Metode Dereferensi mendereferensikan objek. Metode ini dapat digunakan untuk mendereferensikan referensi berbasis model data (ObjectTargetObjectReference, ObjectKeyReference) atau referensi bahasa asli (pointer atau referensi bahasa). Penting untuk dicatat bahwa metode ini menghapus satu tingkat semantik referensi pada objek . Dimungkinkan sepenuhnya untuk, misalnya, memiliki referensi model data ke referensi bahasa. Dalam kasus seperti itu, memanggil metode Dereferensi untuk pertama kalinya akan menghapus referensi model data dan meninggalkan referensi bahasa. Memanggil Dereferensi pada objek yang dihasilkan kemudian akan menghapus referensi bahasa dan mengembalikan nilai asli di bawah referensi tersebut.

Metode Manipulasi Kunci

Setiap objek sintetis yang merupakan kamus tuple kunci, nilai, dan metadata memiliki serangkaian metode untuk memanipulasi kunci, nilai, dan metadata yang terkait dengannya.

Bentuk berbasis nilai API adalah:

STDMETHOD(GetKeyValue)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(SetKeyValue)(_In_ PCWSTR key, _In_opt_ IModelObject* object) PURE;
STDMETHOD(EnumerateKeyValues)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
The key based forms of the APIs (including those used for key creation) are: 
STDMETHOD(GetKey)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(SetKey)(_In_ PCWSTR key, _In_opt_ IModelObject* object, _In_opt_ IKeyStore* metadata) PURE;
STDMETHOD(EnumerateKeys)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
STDMETHOD(ClearKeys)() PURE;

Bentuk api berbasis referensi adalah:

STDMETHOD(GetKeyReference)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** objectReference, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(EnumerateKeyReferences)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;

GetKeyValue

Metode GetKeyValue adalah metode pertama yang akan dialihkan klien untuk mendapatkan nilai (dan metadata yang terkait dengan) kunci tertentu berdasarkan nama. Jika kuncinya adalah pengakses properti -- yaitu nilainya sebagai IModelObject yang merupakan IModelPropertyAccessor dalam kotak, metode GetKeyValue akan secara otomatis memanggil metode GetValue pengakses properti untuk mengambil nilai aktual.

SetKeyValue

Metode SetKeyValue adalah metode pertama yang akan dialihkan klien untuk mengatur nilai kunci. Metode ini tidak dapat digunakan untuk membuat kunci baru pada objek. Ini hanya akan menetapkan nilai kunci yang ada. Perhatikan bahwa banyak kunci bersifat baca-saja (misalnya: kunci tersebut diimplementasikan oleh pengakses properti yang mengembalikan E_NOT_IMPL dari metode SetValue). Metode ini akan gagal ketika dipanggil pada kunci baca-saja.

EnumerateKeyValues

Metode EnumerateKeyValues adalah metode pertama yang akan dialihkan klien untuk menghitung semua kunci pada objek (ini termasuk semua kunci yang diterapkan di mana saja di pohon model induk). Penting untuk dicatat bahwa EnumerateKeyValues akan menghitung kunci apa pun yang ditentukan oleh nama duplikat di pohon objek; namun -- metode seperti GetKeyValue dan SetKeyValue hanya akan memanipulasi instans pertama kunci dengan nama yang diberikan seperti yang ditemukan oleh depth-first-traversal.

GetKey

Metode GetKey akan mendapatkan nilai (dan metadata yang terkait dengan) kunci tertentu berdasarkan nama. Sebagian besar klien harus menggunakan metode GetKeyValue sebagai gantinya. Jika kuncinya adalah pengakses properti, memanggil metode ini akan mengembalikan pengakses properti (antarmuka IModelPropertyAccessor) yang dikotak ke dalam IModelObject. Tidak seperti GetKeyValue, metode ini tidak akan secara otomatis menyelesaikan nilai kunci yang mendasar dengan memanggil metode GetValue. Tanggung jawab itu milik penelepon.

SetKey

Metode SetKey adalah metode yang akan diaktifkan klien untuk membuat kunci pada objek (dan berpotensi mengaitkan metadata dengan kunci yang dibuat). Jika objek tertentu sudah memiliki kunci dengan nama yang diberikan, salah satu dari dua perilaku akan terjadi. Jika kunci ada pada instans yang diberikan oleh ini, nilai kunci tersebut akan diganti seolah-olah kunci asli tidak ada. Jika, di sisi lain, kunci berada dalam rantai model data induk instans yang diberikan oleh ini, kunci baru dengan nama yang diberikan akan dibuat pada instans yang diberikan oleh ini. Hal ini akan, berlaku, menyebabkan objek memiliki dua kunci dengan nama yang sama (mirip dengan kelas turunan yang membayangi anggota dengan nama yang sama dengan kelas dasar).

EnumerateKeys

Metode EnumerateKeys berperilaku mirip dengan metode EnumerateKeyValues kecuali tidak secara otomatis menyelesaikan pengaktif properti pada objek. Ini berarti bahwa jika nilai kunci adalah pengakses properti, metode EnumerateKeys akan mengembalikan pengakses properti (IModelPropertyAccessorInterface) yang dikotak ke dalam IModelObject daripada secara otomatis memanggil metode GetValue. Ini mirip dengan perbedaan antara GetKey dan GetKeyValue.

ClearKeys

Metode ClearKeys menghapus semua kunci dan nilai dan metadata terkait dari instans objek yang ditentukan oleh ini. Metode ini tidak berpengaruh pada model induk yang melekat pada instans objek tertentu.

GetKeyReference

Metode GetKeyReference akan mencari kunci nama yang diberikan pada objek (atau rantai model induknya) dan mengembalikan referensi ke kunci yang diberikan oleh antarmuka IModelKeyReference yang dikotak ke dalam IModelObject. Referensi tersebut kemudian dapat digunakan untuk mendapatkan atau mengatur nilai kunci.

EnumerateKeyReferences

Metode EnumerateKeyReferences berperilaku mirip dengan metode EnumerateKeyValues kecuali bahwa metode tersebut mengembalikan referensi ke kunci yang dihitungnya (diberikan oleh antarmuka IModelKeyReference yang dikotak ke dalam IModelObject) alih-alih nilai kunci. Referensi tersebut dapat digunakan untuk mendapatkan atau mengatur nilai kunci yang mendasar.

Metode Manipulasi Konsep

Selain objek model yang menjadi kamus tuple kunci/nilai/metadata, ini juga merupakan kontainer konsep. Konsep adalah sesuatu yang abstrak yang dapat dilakukan pada atau oleh objek. Konsepnya adalah, pada dasarnya, penyimpanan dinamis antarmuka yang didukung objek. Sejumlah konsep didefinisikan oleh model data saat ini:

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.

Metode berikut pada IModelObject digunakan untuk memanipulasi konsep yang didukung objek.

STDMETHOD(GetConcept)(_In_ REFIID conceptId, _COM_Outptr_ IUnknown** conceptInterface, _COM_Outptr_opt_result_maybenull_ IKeyStore** conceptMetadata) PURE;
STDMETHOD(SetConcept)(_In_ REFIID conceptId, _In_ IUnknown* conceptInterface, _In_opt_ IKeyStore* conceptMetadata) PURE;
STDMETHOD(ClearConcepts)() PURE;

GetConcept

Metode GetConcept akan mencari konsep pada objek (atau rantai model induknya) dan mengembalikan penunjuk antarmuka ke antarmuka konsep. Perilaku dan metode pada antarmuka konsep khusus untuk setiap konsep. Namun, penting untuk dicatat bahwa banyak antarmuka konsep mengharuskan pemanggil untuk secara eksplisit meneruskan objek konteks (atau apa yang mungkin secara tradisional memanggil pointer ini). Penting untuk memastikan bahwa objek konteks yang benar diteruskan ke setiap antarmuka konsep.

SetConcept

Metode SetConcept akan menempatkan konsep tertentu pada instans objek yang ditentukan oleh pointer ini. Jika model induk yang dilampirkan ke instans objek yang ditentukan oleh ini juga mendukung konsep, implementasi dalam instans akan mengambil alihnya dalam model induk.

ClearConcepts

Metode ClearConcepts akan menghapus semua konsep dari instans objek yang ditentukan oleh ini.

Metode Objek Asli

Meskipun banyak objek model mengacu pada intrinsik (misalnya: bilangan bulat, string) atau konstruksi sintetis (kamus tuple dan konsep kunci/nilai/metadata), objek model juga dapat merujuk ke konstruksi asli (misalnya: jenis yang ditentukan pengguna dalam ruang alamat target debug). Antarmuka IModelObject memiliki serangkaian metode di dalamnya yang mengakses informasi tentang objek asli tersebut. Metode tersebut adalah:

STDMETHOD(GetRawValue)(_In_ SymbolKind kind, _In_ PCWSTR name, _In_ ULONG searchFlags, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(EnumerateRawValues)(_In_ SymbolKind kind, _In_ ULONG searchFlags, _COM_Outptr_ IRawEnumerator** enumerator) PURE;
STDMETHOD(TryCastToRuntimeType)(_COM_Errorptr_ IModelObject** runtimeTypedObject) PURE;
STDMETHOD(GetLocation)(_Out_ Location* location) PURE;
STDMETHOD(GetTypeInfo)(_Out_ IDebugHostType** type) PURE;
STDMETHOD(GetTargetInfo)(_Out_ Location* location, _Out_ IDebugHostType** type) PURE;
STDMETHOD(GetRawReference)(_In_ SymbolKind kind, _In_ PCWSTR name, _In_ ULONG searchFlags, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(EnumerateRawReferences)(_In_ SymbolKind kind, _In_ ULONG searchFlags, _COM_Outptr_ IRawEnumerator** enumerator) PURE;

GetRawValue

Metode GetRawValue menemukan konstruksi asli dalam objek yang diberikan. Konstruksi seperti itu mungkin bidang, kelas dasar, bidang di kelas dasar, fungsi anggota, dll...

EnumerateRawValues

Metode EnumerateRawValues menghitung semua anak asli (misalnya: bidang, kelas dasar, dll...) dari objek yang diberikan.

TryCastToRuntimeType

Metode TryCastToRuntimeType akan meminta host debug untuk melakukan analisis dan menentukan jenis runtime aktual (misalnya: kelas yang paling turunan) dari objek yang diberikan. Analisis yang tepat yang digunakan khusus untuk host debug dan dapat mencakup informasi jenis waktu proses RTTI (C++), pemeriksaan struktur V-Table (tabel fungsi virtual) objek, atau cara lain yang dapat digunakan host untuk menentukan jenis dinamis/runtime secara andal dari jenis statis. Kegagalan untuk mengonversi ke jenis runtime tidak berarti bahwa panggilan metode ini akan gagal. Dalam kasus seperti itu, metode akan mengembalikan objek yang diberikan (pointer ini) dalam argumen output.

GetLocation

Metode GetLocation akan mengembalikan lokasi objek asli. Meskipun lokasi seperti itu biasanya merupakan alamat virtual dalam ruang alamat target debug, itu belum tentu demikian. Lokasi yang dikembalikan oleh metode ini adalah lokasi abstrak yang mungkin merupakan alamat virtual, dapat menunjukkan penempatan dalam register atau sub-register, atau mungkin menunjukkan beberapa ruang alamat arbitrer lainnya seperti yang didefinisikan oleh host debug. Jika bidang HostDefined dari objek Lokasi yang dihasilkan adalah 0, itu menunjukkan bahwa lokasi sebenarnya adalah alamat virtual. Alamat virtual tersebut dapat diambil dengan memeriksa bidang Offset dari lokasi yang dihasilkan. Nilai bukan nol dari bidang HostDefined menunjukkan ruang alamat alternatif di mana bidang Offset adalah offset dalam ruang alamat tersebut. Arti pasti dari nilai HostDefined non-nol di sini bersifat privat untuk host debug.

GetTypeInfo

Metode GetTypeInfo akan mengembalikan jenis asli objek yang diberikan. Jika objek tidak memiliki informasi jenis asli yang terkait dengannya (misalnya: itu adalah intrinsik, dll...), panggilan akan tetap berhasil tetapi akan mengembalikan null.

GetTargetInfo

Metode GetTargetInfo secara efektif merupakan kombinasi dari metode GetLocation dan GetTypeInfo yang mengembalikan lokasi abstrak serta jenis asli objek yang diberikan.

GetRawReference

Metode GetRawReference menemukan konstruksi asli dalam objek yang diberikan dan mengembalikan referensi ke dalamnya. Konstruksi seperti itu mungkin bidang, kelas dasar, bidang di kelas dasar, fungsi anggota, dll... Penting untuk membedakan referensi yang dikembalikan di sini (objek jenis ObjectTargetObjectReference) dari referensi bahasa (misalnya: referensi gaya C++ & atau gaya && ).

EnumerateRawReferences

Metode EnumerateRawReferences menghitung referensi ke semua anak asli (misalnya: bidang, kelas dasar, dll...) dari objek yang diberikan.

Metode Ekstensibilitas

Seperti yang dijelaskan sebelumnya, objek model berkinerja sangat mirip dengan objek JavaScript dan rantai prototipenya. Selain instans yang diwakili oleh antarmuka IModelObject tertentu, mungkin ada jumlah model induk arbitrer yang melekat pada objek (yang masing-masing dapat, pada gilirannya, memiliki jumlah model induk arbitrer yang melekat padanya). Ini adalah sarana utama untuk ekstensibilitas dalam model data. Jika properti atau konsep tertentu tidak dapat ditemukan dalam instans tertentu, pencarian yang mengutamakan kedalaman pohon objek (ditentukan oleh model induk) yang berakar pada instans dilakukan.

Metode berikut memanipulasi rantai model induk yang terkait dengan instans IModelObject tertentu:

STDMETHOD(GetNumberOfParentModels)(_Out_ ULONG64* numModels) PURE;
STDMETHOD(GetParentModel)(_In_ ULONG64 i, _COM_Outptr_ IModelObject **model, _COM_Outptr_result_maybenull_ IModelObject **contextObject) PURE;
STDMETHOD(AddParentModel)(_In_ IModelObject* model, _In_opt_ IModelObject* contextObject, _In_ bool override) PURE;
STDMETHOD(RemoveParentModel)(_In_ IModelObject* model) PURE;
STDMETHOD(SetContextForDataModel)(_In_ IModelObject* dataModelObject, _In_ IUnknown* context) PURE;
STDMETHOD(GetContextForDataModel)(_In_ IModelObject* dataModelObject, _Out_ IUnknown** context) PURE;

GetNumberOfParentModels

Metode GetNumberOfParentModels mengembalikan jumlah model induk yang dilampirkan ke instans objek yang diberikan. Model induk dicari untuk properti yang mengutamakan kedalaman dalam urutan linier rantai model induk.

GetParentModel

Metode GetParentModel mengembalikan model induk ke-i dalam rantai model induk objek yang diberikan. Model induk dicari untuk properti atau konsep dalam urutan linier yang ditambahkan atau dijumlahkan. Model induk dengan indeks i dari nol dicari (secara hierarki) sebelum model induk dengan indeks i + 1.

AddParentModel

Metode AddParentModel menambahkan model induk baru ke objek yang diberikan. Model tersebut dapat ditambahkan di akhir rantai pencarian (argumen penimpaan ditentukan sebagai false) atau di bagian depan rantai pencarian (argumen ambil alih ditentukan sebagai true). Selain itu, setiap model induk dapat secara opsional menyesuaikan konteks (semantik penunjuk ini) untuk properti atau konsep apa pun pada induk yang diberikan (atau siapa pun dalam hierarki induknya). Penyesuaian konteks jarang digunakan tetapi memungkinkan beberapa konsep kuat seperti penyematan objek, membangun namespace layanan, dll...

RemoveParentModel

RemoveParentModel akan menghapus model induk tertentu dari rantai pencarian induk objek yang diberikan.

SetContextForDataModel

Metode SetContextForDataModel digunakan oleh implementasi model data untuk menempatkan data implementasi pada objek instans. Secara konseptual, setiap IModelObject (sebut ini instans untuk kesederhanaan) berisi tabel status hash. Tabel hash diindeks oleh IModelObject lain (sebut ini model data untuk kesederhanaan) yang berada dalam hierarki model induk instans. Nilai yang terkandung dalam hash ini adalah sekumpulan referensi yang dihitung informasi status yang diwakili oleh instans IUnknown. Setelah model data menetapkan status ini pada instans, model data dapat menyimpan data implementasi arbitrer yang dapat diambil selama hal-hal seperti pengambili properti.

GetContextForDataModel

Metode GetContextForDataModel digunakan untuk mengambil informasi konteks yang disiapkan dengan panggilan sebelumnya ke SetContextForDataModel. Ini mengambil informasi status yang diatur pada objek instans oleh model data lebih lanjut dalam hierarki model induk objek instans. Untuk detail selengkapnya tentang konteks/status ini dan maknanya, lihat dokumentasi untuk SetContextForDataModel.

Tipe Objek Inti Model Data Debugger

Objek dalam model data mirip dengan gagasan Objek di .NET. Ini adalah kontainer generik tempat pembuatan yang dipahami model data dapat dikotak. Selain objek asli dan objek sintetis (dinamis), ada serangkaian jenis objek inti yang dapat ditempatkan (atau dikotak) ke dalam kontainer IModelObject. Kontainer tempat sebagian besar nilai ini ditempatkan adalah VARIAN COM/OLE standar dengan sejumlah batasan tambahan yang ditempatkan pada apa yang dapat dimuat VARIAN tersebut. Jenis yang paling mendasar dari ini adalah:

  • Nilai 8-bit yang tidak ditandatangani dan ditandatangani (VT_UI1, VT_I1)
  • Nilai 16-bit yang tidak ditandatangani dan ditandatangani (VT_UI2, VT_UI2)
  • Nilai 32-bit yang tidak ditandatangani dan ditandatangani (VT_UI4, VT_I4)
  • Nilai 64-bit yang tidak ditandatangani dan ditandatangani (VT_UI8, VT_I8)
  • Nilai titik float presisi tunggal dan ganda (VT_R4, VT_R8)
  • String (VT_BSTR)
  • Boolean (VT_BOOL)

Selain jenis dasar ini, sejumlah objek model data inti ditempatkan ke dalam IModelObject yang ditentukan oleh VT_UNKNOWN di mana IUnknown yang disimpan dijamin untuk mengimplementasikan antarmuka tertentu. Jenis-jenisnya adalah:

  • Pengakses properti (IModelPropertyAccessor)
  • Objek metode (IModelMethod)
  • Objek referensi utama (IModelKeyReference atau IModelKeyReference2)
  • Objek konteks (IDebugModelHostContext)

Pengakses Properti: IModelPropertyAccessor

Pengakses properti dalam model data adalah implementasi antarmuka IModelPropertyAccessor yang dikotak ke dalam IModelObject. Objek model akan mengembalikan semacam ObjectPropertyAccessor ketika dikueri dan nilai intrinsik adalah VT_UNKNOWN yang dijamin dapat dikueri untuk IModelPropertyAccessor. Dalam prosesnya, dijamin akan ditransmisikan secara statis ke IModelPropertyAccessor.

Pengakses properti adalah cara tidak langsung untuk mendapatkan panggilan metode untuk mendapatkan dan menetapkan nilai kunci dalam model data. Jika nilai kunci yang diberikan adalah pengakses properti, metode GetKeyValue dan SetKeyValue akan secara otomatis melihat ini dan memanggil metode GetValue atau SetValue yang mendasar pengakses properti sebagaimana mewajibkan.

Antarmuka IModelPropertyAccessor didefinisikan sebagai berikut:

DECLARE_INTERFACE_(IModelPropertyAccessor, IUnknown)
{
    STDMETHOD(GetValue)(_In_ PCWSTR key, _In_opt_ IModelObject* contextObject, _COM_Outptr_ IModelObject** value) PURE;
    STDMETHOD(SetValue)(_In_ PCWSTR key, _In_opt_ IModelObject* contextObject, _In_ IModelObject* value) PURE; 
}

GetValue

Metode GetValue adalah getter untuk pengaktor properti. Ini dipanggil setiap kali klien ingin mengambil nilai properti yang mendasar. Perhatikan bahwa setiap penelepon yang secara langsung mendapatkan pengakses properti bertanggung jawab untuk meneruskan nama kunci dan objek instans yang akurat (penunjuk ini) ke metode GetValue pengakses properti.

SetValue

Metode SetValue adalah setter untuk pengaktor properti. Ini dipanggil setiap kali klien ingin menetapkan nilai ke properti yang mendasar. Banyak properti bersifat baca-saja. Dalam kasus seperti itu, memanggil metode SetValue akan mengembalikan E_NOTIMPL. Perhatikan bahwa setiap penelepon yang secara langsung mendapatkan pengakses properti bertanggung jawab untuk meneruskan nama kunci dan objek instans yang akurat (penunjuk ini) ke metode SetValue pengakses properti.

Metode: IModelMethod

Metode dalam model data adalah implementasi antarmuka IModelMethod yang dikemas ke dalam IModelObject. Objek model akan mengembalikan semacam ObjectMethod ketika dikueri dan nilai intrinsik adalah VT_UNKNOWN yang dijamin dapat dikueri untuk IModelMethod. Dalam prosesnya, dijamin dapat ditransmisikan secara statis ke IModelMethod. Semua metode dalam model data bersifat dinamis. Mereka mengambil sebagai input satu set argumen 0 atau lebih dan mengembalikan satu nilai output. Tidak ada resolusi kelebihan beban dan tidak ada metadata tentang nama parameter, jenis, atau ekspektasi.

Antarmuka IModelMethod didefinisikan sebagai berikut:

DECLARE_INTERFACE_(IModelMethod, IUnknown)
{
    STDMETHOD(Call)(_In_opt_ IModelObject *pContextObject, _In_ ULONG64 argCount, _In_reads_(argCount) IModelObject **ppArguments, _COM_Errorptr_ IModelObject **ppResult, _COM_Outptr_opt_result_maybenull_ IKeyStore **ppMetadata) PURE;
}

Panggil

Metode Panggilan adalah cara di mana metode apa pun yang ditentukan dalam model data dipanggil. Pemanggil bertanggung jawab untuk meneruskan objek instans yang akurat (penunjuk ini) dan sekumpulan argumen arbitrer. Hasil metode dan metadata opsional apa pun yang terkait dengan hasil tersebut dikembalikan. Metode yang tidak secara logis mengembalikan nilai masih harus mengembalikan IModelObject yang valid. Dalam kasus seperti itu, IModelObject adalah nilai tanpa kotak. Jika metode gagal, metode dapat mengembalikan informasi kesalahan opsional yang diperluas dalam argumen input (bahkan jika HRESULT yang dikembalikan adalah kegagalan). Sangat penting bahwa penelepon memeriksa ini.

Referensi Utama: IModelKeyReference atau IModelKeyReference2

Referensi utamanya adalah, pada dasarnya, handel ke kunci pada objek tertentu. Klien dapat mengambil handel tersebut melalui metode seperti GetKeyReference dan menggunakan handel nanti untuk mendapatkan atau mengatur nilai kunci tanpa harus memegang objek asli. Jenis objek ini adalah implementasi dari antarmuka IModelKeyReference atau IModelKeyReference2 yang dikemas ke dalam IModelObject. Objek model akan mengembalikan semacam ObjectKeyReference ketika dikueri dan kemudian nilai intrinsik adalah VT_UNKNOWN yang dijamin dapat dikueri untuk IModelKeyReference. Dalam prosesnya, dijamin dapat ditransmisikan secara statis ke IModelKeyReference.

Antarmuka referensi utama didefinisikan sebagai berikut:

DECLARE_INTERFACE_(IModelKeyReference2, IModelKeyReference)
{
    STDMETHOD(GetKeyName)(_Out_ BSTR* keyName) PURE;
    STDMETHOD(GetOriginalObject)(_COM_Outptr_ IModelObject** originalObject) PURE;
    STDMETHOD(GetContextObject)(_COM_Outptr_ IModelObject** containingObject) PURE;
    STDMETHOD(GetKey)(_COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
    STDMETHOD(GetKeyValue)(_COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
    STDMETHOD(SetKey)(_In_opt_ IModelObject* object, _In_opt_ IKeyStore* metadata) PURE;
    STDMETHOD(SetKeyValue)(_In_ IModelObject* object) PURE;
    STDMETHOD(OverrideContextObject)(_In_ IModelObject* newContextObject) PURE;
}

GetKeyName

Metode GetKeyName mengembalikan nama kunci yang menjadi pegangan referensi kunci ini. String yang dikembalikan adalah BSTR standar dan harus dibebaskan melalui panggilan ke SysFreeString.

GetOriginalObject

Metode GetOriginalObject mengembalikan objek instans tempat referensi kunci dibuat. Perhatikan bahwa kunci itu sendiri mungkin ada pada model induk objek instans.

GetContextObject

Metode GetContextObject mengembalikan konteks (penunjuk ini) yang akan diteruskan ke metode GetValue atau SetValue pengakses properti jika kunci yang dimaksud mengacu pada pengakses properti. Objek konteks yang dikembalikan di sini mungkin atau mungkin tidak sama dengan objek asli yang diambil dari GetOriginalObject. Jika kunci berada pada model induk dan ada penyesuaian konteks yang terkait dengan model induk tersebut, objek asli adalah objek instans tempat GetKeyReference atau EnumerateKeyReferences dipanggil. Objek konteks akan menjadi apa pun yang keluar dari penyesuaian konteks akhir antara objek asli dan model induk yang berisi kunci yang menjadi pegangan referensi kunci ini. Jika tidak ada penyesuaian konteks, objek asli dan objek konteks identik.

GetKey

Metode GetKey pada referensi kunci berperilaku seperti metode GetKey pada IModelObject. Ini mengembalikan nilai kunci yang mendasar dan metadata apa pun yang terkait dengan kunci. Jika nilai kunci kebetulan adalah pengakses properti, ini akan mengembalikan pengakses properti (IModelPropertyAccessor) yang dikotak ke dalam IModelObject. Metode ini tidak akan memanggil metode GetValue atau SetValue yang mendasar pada pengakses properti.

GetKeyValue

Metode GetKeyValue pada referensi kunci berperilaku sebagai metode GetKeyValue pada IModelObject. Ini mengembalikan nilai kunci yang mendasar dan metadata apa pun yang terkait dengan kunci. Jika nilai kunci kebetulan adalah pengakses properti, ini akan memanggil metode GetValue yang mendasar pada pengakses properti secara otomatis.

SetKey

Metode SetKey pada referensi kunci berperilaku sebagai metode SetKey pada IModelObject. Ini akan menetapkan nilai kunci. Jika kunci aslinya adalah pengaktor properti, ini akan menggantikan pengaktor properti. Ini tidak akan memanggil metode SetValue pada pengakses properti.

SetKeyValue

Metode SetKeyValue pada referensi kunci berperilaku sebagai metode SetKeyValue pada IModelObject. Ini akan menetapkan nilai kunci. Jika kunci aslinya adalah aksesor properti, ini akan memanggil metode SetValue yang mendasarinya pada aksesor properti daripada mengganti aksesor properti itu sendiri.

OverrideContextObject

Metode OverrideContextObject (hanya ada di IModelKeyReference2) adalah metode lanjutan yang digunakan untuk mengubah objek konteks secara permanen yang akan diteruskan referensi kunci ini ke metode GetValue atau SetValue aksesor properti yang mendasar. Objek yang diteruskan ke metode ini juga akan dikembalikan dari panggilan ke GetContextObject. Metode ini dapat digunakan oleh penyedia skrip untuk mereplikasi perilaku bahasa dinamis tertentu. Sebagian besar klien tidak boleh memanggil metode ini.

Objek Konteks: IDebugHostContext

Objek konteks adalah blob buram informasi yang dikaitkan oleh host debug (bekerja sama dengan model data) dengan setiap objek. Ini mungkin termasuk hal-hal seperti konteks proses atau ruang alamat asal informasi, dll... Objek konteks adalah implementasi IDebugHostContext yang dikotak dalam IModelObject. Perhatikan bahwa IDebugHostContext adalah antarmuka yang ditentukan host. Klien tidak akan pernah mengimplementasikan antarmuka ini.

Untuk informasi selengkapnya tentang objek konteks, lihat Debugger Data Model C++ Antarmuka Host di Antarmuka C++ Model Data Debugger.

Manajer Model Data

Antarmuka inti untuk manajer model data, IDataModelManager2 (atau IDataModelManager sebelumnya) didefinisikan sebagai berikut:

DECLARE_INTERFACE_(IDataModelManager2, IDataModelManager)
{
    //
    // IDataModelManager:
    //
    STDMETHOD(Close)() PURE;
    STDMETHOD(CreateNoValue)(_Out_ IModelObject** object) PURE;
    STDMETHOD(CreateErrorObject)(_In_ HRESULT hrError, _In_opt_ PCWSTR pwszMessage, _COM_Outptr_ IModelObject** object) PURE;
    STDMETHOD(CreateTypedObject)(_In_opt_ IDebugHostContext* context, _In_ Location objectLocation, _In_ IDebugHostType* objectType, _COM_Errorptr_ IModelObject** object) PURE;
    STDMETHOD(CreateTypedObjectReference)(_In_opt_ IDebugHostContext* context, _In_ Location objectLocation, _In_ IDebugHostType* objectType, _COM_Errorptr_ IModelObject** object) PURE;
    STDMETHOD(CreateSyntheticObject)(_In_opt_ IDebugHostContext* context, _COM_Outptr_ IModelObject** object) PURE;
    STDMETHOD(CreateDataModelObject)(_In_ IDataModelConcept* dataModel, _COM_Outptr_ IModelObject** object) PURE;
    STDMETHOD(CreateIntrinsicObject)(_In_ ModelObjectKind objectKind, _In_ VARIANT* intrinsicData, _COM_Outptr_ IModelObject** object) PURE;
    STDMETHOD(CreateTypedIntrinsicObject)(_In_ VARIANT* intrinsicData, _In_ IDebugHostType* type, _COM_Outptr_ IModelObject** object) PURE;
    STDMETHOD(GetModelForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _Out_ IModelObject** dataModel) PURE;
    STDMETHOD(GetModelForType)(_In_ IDebugHostType* type, _COM_Outptr_ IModelObject** dataModel, _COM_Outptr_opt_ IDebugHostTypeSignature** typeSignature, _COM_Outptr_opt_ IDebugHostSymbolEnumerator** wildcardMatches) PURE;
    STDMETHOD(RegisterModelForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _In_ IModelObject* dataModel) PURE;
    STDMETHOD(UnregisterModelForTypeSignature)(_In_ IModelObject* dataModel, _In_opt_ IDebugHostTypeSignature* typeSignature) PURE;
    STDMETHOD(RegisterExtensionForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _In_ IModelObject* dataModel) PURE;
    STDMETHOD(UnregisterExtensionForTypeSignature)(_In_ IModelObject* dataModel, _In_opt_ IDebugHostTypeSignature* typeSignature) PURE;
    STDMETHOD(CreateMetadataStore)(_In_opt_ IKeyStore* parentStore, _COM_Outptr_ IKeyStore** metadataStore) PURE;
    STDMETHOD(GetRootNamespace)(_COM_Outptr_ IModelObject** rootNamespace) PURE;
    STDMETHOD(RegisterNamedModel)(_In_ PCWSTR modelName, _In_ IModelObject *modeObject) PURE;
    STDMETHOD(UnregisterNamedModel)(_In_ PCWSTR modelName) PURE;
    STDMETHOD(AcquireNamedModel)(_In_ PCWSTR modelName, _COM_Outptr_ IModelObject **modelObject) PURE;
    //
    // IDataModelManager2:
    //
    STDMETHOD(AcquireSubNamespace)(_In_ PCWSTR modelName, _In_ PCWSTR subNamespaceModelName, _In_ PCWSTR accessName, _In_opt_ IKeyStore *metadata, _COM_Outptr_ IModelObject **namespaceModelObject) PURE;
    STDMETHOD(CreateTypedIntrinsicObjectEx)(_In_opt_ IDebugHostContext* context, _In_ VARIANT* intrinsicData, _In_ IDebugHostType* type, _COM_Outptr_ IModelObject** object) PURE;
}

Metode Manajemen

Serangkaian metode berikut digunakan oleh aplikasi (misalnya: debugger) yang menghosting model data.

STDMETHOD(Close)() PURE;

Tutup

Metode Tutup dipanggil pada manajer model data oleh aplikasi (misalnya: debugger) yang menghosting model data untuk memulai proses pematian manajer model data. Host model data yang bukan metode Tutup sebelum merilis referensi akhirnya pada manajer model data dapat menyebabkan perilaku yang tidak terdefinisi termasuk, tetapi tidak terbatas pada, kebocoran signifikan infrastruktur manajemen untuk model data.

Pembuatan Objek / Metode Tinju

Set metode berikut digunakan untuk membuat objek baru atau untuk mengemas nilai ke dalam IModelObject -- antarmuka inti model data.

STDMETHOD(CreateNoValue)(_Out_ IModelObject** object) PURE;
STDMETHOD(CreateErrorObject)(_In_ HRESULT hrError, _In_opt_ PCWSTR pwszMessage, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateTypedObject)(_In_opt_ IDebugHostContext* context, _In_ Location objectLocation, _In_ IDebugHostType* objectType, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(CreateTypedObjectReference)(_In_opt_ IDebugHostContext* context, _In_ Location objectLocation, _In_ IDebugHostType* objectType, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(CreateSyntheticObject)(_In_opt_ IDebugHostContext* context, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateDataModelObject)(_In_ IDataModelConcept* dataModel, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateIntrinsicObject)(_In_ ModelObjectKind objectKind, _In_ VARIANT* intrinsicData, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateTypedIntrinsicObject)(_In_ VARIANT* intrinsicData, _In_ IDebugHostType* type, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateMetadataStore)(_In_opt_ IKeyStore* parentStore, _COM_Outptr_ IKeyStore** metadataStore) PURE;
STDMETHOD(CreateTypedIntrinsicObjectEx)(_In_opt_ IDebugHostContext* context, _In_ VARIANT* intrinsicData, _In_ IDebugHostType* type, _COM_Outptr_ IModelObject** object) PURE;

CreateNoValue

Metode CreateNoValue membuat objek "tanpa nilai", menkotaknya ke dalam IModelObject, dan mengembalikannya. Objek model yang dikembalikan memiliki semacam ObjectNoValue.

Objek "tanpa nilai" memiliki beberapa arti semantik:

  • (Tergantung pada bahasa), itu dapat dianggap setara semantik kekosongan, null, atau tidak terdefinisi
  • Metode GetValue pengakses properti apa pun yang mengembalikan keberhasilan dan objek "tanpa nilai" yang dihasilkan menunjukkan bahwa properti tertentu tidak memiliki nilai untuk instans yang diberikan dan harus diperlakukan seolah-olah properti tidak ada untuk instans tertentu.
  • Metode model data yang tidak secara semantik memiliki nilai pengembalian menggunakan ini sebagai sentinel untuk menunjukkan seperti itu (sebagai metode harus mengembalikan IModelObject yang valid).

CreateErrorObject

Metode CreateErrorObject membuat "objek kesalahan". Model data tidak memiliki gagasan pengecualian dan alur pengecualian. Kegagalan keluar dari properti/metode dengan dua cara:

  • Satu HRESULT yang gagal tanpa informasi kesalahan yang diperluas. Tidak ada informasi lagi yang dapat diberikan untuk kesalahan atau kesalahan itu sendiri jelas dari HRESULT yang dikembalikan.
  • Satu HRESULT yang gagal ditambah dengan informasi kesalahan yang diperluas. Informasi kesalahan yang diperluas adalah objek kesalahan yang dikembalikan dalam argumen output properti/metode.

CreateTypedObject

Metode CreateTypedObject adalah metode yang memungkinkan klien membuat representasi objek asli/bahasa di ruang alamat target debug. Jika jenis objek yang baru dibuat (seperti yang ditunjukkan oleh argumen objectType) kebetulan cocok dengan satu atau beberapa jenis tanda tangan yang terdaftar di manajer model data sebagai visualizer atau ekstensi kanonis, model data yang cocok tersebut akan secara otomatis dilampirkan ke objek instans yang dibuat sebelum dikembalikan ke pemanggil.

CreateTypedObjectReference

Metode CreateTypedObjectReference secara semantik mirip dengan metode CreateTypedObject kecuali membuat referensi ke konstruksi asli/bahasa yang mendasar. Referensi yang dibuat adalah objek yang memiliki semacam ObjectTargetObjectReference. Ini bukan referensi asli karena bahasa yang mendasar mungkin mendukung (misalnya: & C++ atau &&). Dimungkinkan untuk memiliki ObjectTargetObjectReference ke referensi C++. Objek jenis ObjectTargetObjectReference dapat dikonversi ke nilai yang mendasar melalui penggunaan metode Dereferensi pada IModelObject. Referensi juga dapat diteruskan ke evaluator ekspresi host yang mendasar untuk menetapkan kembali ke nilai dengan bahasa yang sesuai.

CreateSyntheticObject

Metode CreateSyntheticObject membuat objek model data kosong -- kamus tuple dan konsep kunci/nilai/metadata. Pada saat pembuatan, tidak ada kunci atau konsep pada objek . Ini adalah garis miring yang bersih untuk digunakan pemanggil.

CreateDataModelObject

Metode CreateDataModelObject adalah pembungkus pembantu sederhana untuk membuat objek yang merupakan model data -- yaitu objek yang akan dilampirkan sebagai model induk ke objek lain. Semua objek tersebut harus mendukung konsep model data melalui IDataModelConcept. Metode ini membuat objek sintetis kosong baru tanpa konteks eksplisit dan menambahkan IDataModelConcept yang diinpass sebagai implementasi objek yang baru dibuat dari konsep model data. Ini juga dapat dicapai dengan panggilan ke CreateSyntheticObject dan SetConcept.

CreateIntrinsicObject

Metode CreateIntrinsicObject adalah metode yang mengelompokkan nilai intrinsik ke dalam IModelObject. Pemanggil menempatkan nilai dalam VARIAN COM dan memanggil metode ini. Manajer model data mengembalikan IModelObject yang mewakili objek . Perhatikan bahwa metode ini juga digunakan untuk mengetik jenis dasar berbasis IUnknown: pengakses properti, metode, konteks, dll... Dalam kasus seperti itu, metode objectKind menunjukkan jenis konstruksi berbasis IUnknown apa yang diwakili objek dan bidang punkVal dari varian yang diteruskan adalah jenis turunan IUnknown. Jenis harus secara statis dapat ditransmisikan ke antarmuka model yang sesuai (misalnya: IModelPropertyAccessor, IModelMethod, IDebugHostContext, dll...) dalam proses. Jenis VARIAN yang didukung oleh metode ini adalah VT_UI1, VT_I1, VT_UI2, VT_I2, VT_UI4, VT_I4, VT_UI8, VT_I8, VT_R4, VT_R8, VT_BOOL, VT_BSTR, dan VT_UNKNOWN (untuk set khusus jenis turunan IUnknown seperti yang ditunjukkan oleh model enumerasiObjectKind.

CreateTypedIntrinsicObject

Metode CreateTypedintrinsicObject mirip dengan metode CreateIntrinsicObject kecuali memungkinkan jenis asli/bahasa dikaitkan dengan data dan dibawa bersama dengan nilai kotak. Ini memungkinkan model data untuk mewakili konstruksi seperti jenis enumerasi asli (yang hanya VT_UI* atau nilai VT_I*). Jenis pointer juga dibuat dengan metode ini. Penunjuk asli dalam model data adalah kuantitas 64-bit nol yang diperluas yang mewakili offset ke dalam ruang alamat virtual target debug. Ini dikotak di dalam VT_UI8 dan dibuat dengan metode ini dan jenis yang menunjukkan penunjuk asli/bahasa.

CreateMetadataStore

Metode CreateMetadataStore membuat penyimpanan kunci -- kontainer tuple kunci/nilai/metadata yang disederhanakan -- yang digunakan untuk menyimpan metadata yang dapat dikaitkan dengan properti dan berbagai nilai lainnya. Penyimpanan metadata mungkin memiliki satu induk (yang pada gilirannya dapat memiliki satu induk). Jika kunci metadata tertentu tidak terletak di penyimpanan tertentu, induknya akan diperiksa. Sebagian besar penyimpanan metadata tidak memiliki orang tua. Namun, hal ini memberikan cara berbagi metadata umum dengan mudah.

CreateTypedIntrinsicObjectEx

Metode CreateTypedIntrinsicObjectEx secara semantik mirip dengan metode CreateTypedIntrinsicObject. Satu-satunya perbedaan antara keduanya adalah bahwa metode ini memungkinkan pemanggil untuk menentukan konteks di mana data intrinsik valid. Jika tidak ada konteks yang diteruskan, data dianggap valid dalam konteks apa pun yang diwarisi dari argumen jenis (bagaimana createTypedIntrinsicObject berperilaku). Ini memungkinkan pembuatan nilai penunjuk yang ditik dalam target debug yang memerlukan konteks yang lebih spesifik daripada yang dapat diwarisi dari jenis .

Ekstensibilitas / Metode Pendaftaran Serangkaian metode berikut mengelola mekanisme ekstensibilitas model data, memungkinkan klien untuk memperluas atau mendaftarkan model yang ada atau meminta model data untuk secara otomatis melampirkan model induk tertentu pada jenis asli yang cocok dengan kriteria tertentu.

    STDMETHOD(GetModelForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _Out_ IModelObject** dataModel) PURE;
    STDMETHOD(GetModelForType)(_In_ IDebugHostType* type, _COM_Outptr_ IModelObject** dataModel, _COM_Outptr_opt_ IDebugHostTypeSignature** typeSignature, _COM_Outptr_opt_ IDebugHostSymbolEnumerator** wildcardMatches) PURE;
    STDMETHOD(RegisterModelForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _In_ IModelObject* dataModel) PURE;
    STDMETHOD(UnregisterModelForTypeSignature)(_In_ IModelObject* dataModel, _In_opt_ IDebugHostTypeSignature* typeSignature) PURE;
    STDMETHOD(RegisterExtensionForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _In_ IModelObject* dataModel) PURE;
    STDMETHOD(UnregisterExtensionForTypeSignature)(_In_ IModelObject* dataModel, _In_opt_ IDebugHostTypeSignature* typeSignature) PURE;
    STDMETHOD(GetRootNamespace)(_COM_Outptr_ IModelObject** rootNamespace) PURE;
    STDMETHOD(RegisterNamedModel)(_In_ PCWSTR modelName, _In_ IModelObject *modeObject) PURE;
    STDMETHOD(UnregisterNamedModel)(_In_ PCWSTR modelName) PURE;
    STDMETHOD(AcquireNamedModel)(_In_ PCWSTR modelName, _COM_Outptr_ IModelObject **modelObject) PURE;

GetModelForTypeSignature

Metode GetModelForTypeSignature mengembalikan model data yang didaftarkan terhadap tanda tangan jenis tertentu melalui panggilan sebelumnya ke metode RegisterModelForTypeSignature. Model data yang dikembalikan dari metode ini dianggap sebagai visualizer kanonis untuk jenis apa pun yang cocok dengan tanda tangan jenis yang diteruskan. Sebagai visualizer kanonis, model data tersebut mengambil alih tampilan jenis. Mesin tampilan akan, secara default, menyembunyikan konstruksi asli/bahasa objek demi tampilan objek yang disajikan oleh model data.

GetModelForType

Metode GetModelForType mengembalikan model data yang merupakan visualizer kanonis untuk instans jenis tertentu. Akibatnya, metode ini menemukan tanda tangan jenis pencocokan terbaik yang terdaftar dengan panggilan sebelumnya ke metode RegisterModelForTypeSignature dan mengembalikan model data terkait.

RegisterModelForTypeSignature

Metode RegisterModelForTypeSignature adalah metode utama yang digunakan pemanggil untuk mendaftarkan visualizer kanonis untuk jenis tertentu (atau sekumpulan jenis). Visualizer kanonis adalah model data yang, berlaku, mengambil alih tampilan jenis tertentu (atau sekumpulan jenis). Alih-alih tampilan asli/bahasa dari jenis yang ditampilkan di antarmuka pengguna debugger apa pun, tampilan jenis seperti yang disajikan oleh model data terdaftar ditampilkan (bersama dengan sarana untuk kembali ke tampilan asli/bahasa untuk pengguna yang menginginkannya).

UnregisterModelForTypeSignature

Metode UnregisterModelForTypeSignature membatalkan panggilan sebelumnya ke metode RegisterModelForTypeSignature. Metode ini dapat menghapus model data tertentu sebagai penvisualisasi kanonis untuk jenis yang cocok dengan tanda tangan jenis tertentu atau dapat menghapus model data tertentu sebagai visualizer kanonis untuk setiap tanda tangan jenis tempat model data tersebut didaftarkan.

RegisterExtensionForTypeSignature

Metode RegisterExtensionForTypeSignature mirip dengan metode RegisterModelForTypeSignature dengan satu perbedaan utama. Model data yang diteruskan ke metode ini bukan penampil visual kanonis untuk jenis apa pun dan tidak akan mengambil alih tampilan tampilan asli/bahasa dari jenis tersebut. Model data yang diteruskan ke metode ini akan secara otomatis ditambahkan sebagai induk ke jenis beton apa pun yang cocok dengan tanda tangan jenis yang disediakan. Tidak seperti metode RegisterModelForTypeSignature, tidak ada batasan pada tanda tangan jenis yang identik atau ambigu yang didaftarkan sebagai ekstensi ke jenis tertentu (atau set jenis). Setiap ekstensi yang tanda tangan jenisnya cocok dengan instans jenis konkret tertentu akan menyebabkan model data yang terdaftar melalui metode ini secara otomatis dilampirkan ke objek yang baru dibuat sebagai model induk. Ini, berlaku, memungkinkan jumlah klien arbitrer untuk memperluas jenis (atau set jenis) dengan bidang atau fungsionalitas baru.

UnregisterExtensionForTypeSignature

Metode UnregisterExtensionForTypeSignature membatalkan panggilan sebelumnya ke RegisterExtensionForTypeSignature. Ini membatalkan pendaftaran model data tertentu sebagai ekstensi untuk tanda tangan jenis tertentu atau sebagai ekstensi untuk semua jenis tanda tangan tempat model data didaftarkan.

GetRootNamespace

Metode GetRootNamespace mengembalikan namespace layanan akar model data. Ini adalah objek yang dikelola model data dan tempat host debug menempatkan objek tertentu.

RegisterNamedModel

Metode RegisterNamedModel mendaftarkan model data tertentu dengan nama yang terkenal sehingga dapat ditemukan oleh klien yang ingin memperluasnya. Ini adalah tujuan utama API -- untuk menerbitkan model data sebagai sesuatu yang dapat diperluas dengan mengambil model yang terdaftar dengan nama terkenal ini dan menambahkan model induk ke dalamnya.

UnregisterNamedModel

Metode UnregisterNamedModel membatalkan panggilan sebelumnya ke RegisterNamedModel. Ini menghapus hubungan antara model data dan nama di mana ia dapat dicari.

AcquireNamedModel

Penelepon yang ingin memperluas model data yang terdaftar dengan nama tertentu memanggil metode AcquireNamedModel untuk mengambil objek untuk model data yang ingin mereka perluas. Metode ini akan mengembalikan model data apa pun yang didaftarkan melalui panggilan sebelumnya ke metode RegisterNamedModel. Sebagai tujuan utama metode AcquireNamedModel adalah untuk memperluas model, metode ini memiliki perilaku khusus jika belum ada model yang terdaftar dengan nama yang diberikan. Jika belum ada model yang terdaftar dengan nama yang diberikan, objek stub dibuat, didaftarkan sementara dengan nama yang diberikan, dan dikembalikan ke pemanggil. Ketika model data nyata didaftarkan melalui panggilan ke metode RegisterNamedModel, setiap perubahan yang dilakukan pada objek stub, berlaku, dilakukan pada model nyata. Ini menghapus banyak masalah dependensi urutan beban dari komponen yang saling memperluas.

Metode pembantu

Metode berikut adalah metode pembantu umum yang membantu melakukan operasi kompleks pada objek dalam model data. Meskipun dimungkinkan untuk melakukan tindakan ini melalui metode lain pada model data atau objeknya, metode kenyamanan ini membuatnya jauh lebih mudah:

STDMETHOD(AcquireSubNamespace)(_In_ PCWSTR modelName, _In_ PCWSTR subNamespaceModelName, _In_ PCWSTR accessName, _In_opt_ IKeyStore *metadata, _COM_Outptr_ IModelObject **namespaceModelObject) PURE;

AcquireSubNamespace

Metode AcquireSubNamespace membantu dalam pembangunan sesuatu yang mungkin lebih tradisional terlihat seperti namespace bahasa daripada objek baru dalam bahasa dinamis. Jika, misalnya, penelepon ingin mengategorikan properti pada objek proses untuk membuat objek proses lebih terorganisir dan properti lebih mudah ditemukan, salah satu metode untuk melakukan ini adalah membuat sub-objek untuk setiap kategori pada objek proses dan menempatkan properti tersebut di dalam objek tersebut.

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

Model Data Debugger C++ Antarmuka Tambahan

Konsep C++ Model Data Debugger

Pembuatan Skrip C++ Model Data Debugger