Bagikan melalui


Kelas CComObjectRootEx

Kelas ini menyediakan metode untuk menangani manajemen jumlah referensi objek untuk objek nonaggregated dan agregat.

Sintaks

template<class ThreadModel>
class CComObjectRootEx : public CComObjectRootBase

Parameter

ThreadModel
Kelas yang metodenya mengimplementasikan model threading yang diinginkan. Anda dapat secara eksplisit memilih model utas dengan mengatur ThreadModel ke CComSingleThreadModel, CComMultiThreadModel, atau CComMultiThreadModelNoCS. Anda dapat menerima model utas default server dengan mengatur ThreadModel ke CComObjectThreadModel atau CComGlobalsThreadModel.

Anggota

Metode

Fungsi Deskripsi
CComObjectRootEx Konstruktor.
InternalAddRef Menaikkan jumlah referensi untuk objek nonaggregated.
InternalRelease Mengurangi jumlah referensi untuk objek nonaggregated.
Kunci Jika model utas multithread, mendapatkan kepemilikan objek bagian penting.
Membuka Jika model utas multithread, merilis kepemilikan objek bagian penting.

Metode CComObjectRootBase

Fungsi Deskripsi
FinalConstruct Ambil alih di kelas Anda untuk melakukan inisialisasi apa pun yang diperlukan oleh objek Anda.
FinalRelease Ambil alih di kelas Anda untuk melakukan pembersihan apa pun yang diperlukan oleh objek Anda.
OuterAddRef Menaikkan jumlah referensi untuk objek agregat.
OuterQueryInterface Mendelegasikan ke luar IUnknown objek agregat.
OuterRelease Mengurangi jumlah referensi untuk objek agregat.

Fungsi Statis

Fungsi Deskripsi
InternalQueryInterface Mendelegasikan ke IUnknown objek nonaggregated.
ObjectMain Dipanggil selama inisialisasi dan penghentian modul untuk kelas turunan yang tercantum dalam peta objek.

Anggota Data

Anggota data Deskripsi
m_dwRef Dengan m_pOuterUnknown, bagian dari serikat. Digunakan saat objek tidak diagregasi untuk menahan jumlah AddRef referensi dan Release.
m_pOuterUnknown Dengan m_dwRef, bagian dari serikat. Digunakan saat objek diagregasi untuk menahan penunjuk ke luar yang tidak diketahui.

Keterangan

CComObjectRootEx menangani manajemen jumlah referensi objek untuk objek nonaggregated dan agregat. Ini menyimpan jumlah referensi objek jika objek Anda tidak diagregasi, dan menahan penunjuk ke luar yang tidak diketahui jika objek Anda sedang dikumpulkan. Untuk objek agregat, CComObjectRootEx metode dapat digunakan untuk menangani kegagalan objek dalam untuk dibangun, dan untuk melindungi objek luar dari penghapusan ketika antarmuka dalam dirilis atau objek dalam dihapus.

Kelas yang mengimplementasikan server COM harus mewarisi dari CComObjectRootEx atau CComObjectRoot.

Jika definisi kelas Anda menentukan makro DECLARE_POLY_AGGREGATABLE , ATL membuat instans CComPolyObject<CYourClass> kapan IClassFactory::CreateInstance dipanggil. Selama pembuatan, nilai luar yang tidak diketahui diperiksa. Jika null, IUnknown diimplementasikan untuk objek nonaggregated. Jika yang tidak diketahui luar bukan NULL, IUnknown diimplementasikan untuk objek agregat.

Jika kelas Anda tidak menentukan makro DECLARE_POLY_AGGREGATABLE, ATL membuat instans CAggComObject<CYourClass> untuk objek agregat atau instans CComObject<CYourClass> untuk objek nonaggregated.

Keuntungan menggunakannya CComPolyObject adalah Anda menghindari memiliki keduanya CComAggObject dan CComObject dalam modul Anda untuk menangani kasus agregat dan tanpa agregat. Satu CComPolyObject objek menangani kedua kasus. Oleh karena itu, hanya satu salinan vtable dan satu salinan fungsi yang ada di modul Anda. Jika vtable Anda besar, ini dapat secara substansial mengurangi ukuran modul Anda. Namun, jika vtable Anda kecil, penggunaan CComPolyObject dapat mengakibatkan ukuran modul yang sedikit lebih besar karena tidak dioptimalkan untuk objek agregat atau nonaggregated, apa adanya CComAggObject dan CComObject.

Jika objek Anda dikumpulkan, IUnknown diimplementasikan oleh CComAggObject atau CComPolyObject. Kelas-kelas ini mendelegasikan QueryInterface, AddRef, dan Release panggilan ke CComObjectRootEx, OuterQueryInterface, OuterAddRefdan OuterRelease untuk meneruskan ke luar yang tidak diketahui. Biasanya, Anda mengambil alih CComObjectRootEx::FinalConstruct di kelas Anda untuk membuat objek agregat apa pun, dan mengambil alih CComObjectRootEx::FinalRelease untuk membebaskan objek agregat apa pun.

Jika objek Anda tidak diagregasi, IUnknown diimplementasikan oleh CComObject atau CComPolyObject. Dalam hal ini, panggilan ke QueryInterface, AddRef, dan Release didelegasikan ke CComObjectRootEx, InternalQueryInterface, InternalAddRefdan InternalRelease untuk melakukan operasi aktual.

Persyaratan

Header: atlcom.h

CComObjectRootEx::CComObjectRootEx

Konstruktor menginisialisasi jumlah referensi ke 0.

CComObjectRootEx();

CComObjectRootEx::FinalConstruct

Anda dapat mengambil alih metode ini di kelas turunan Anda untuk melakukan inisialisasi apa pun yang diperlukan untuk objek Anda.

HRESULT FinalConstruct();

Tampilkan Nilai

Mengembalikan S_OK pada keberhasilan atau salah satu nilai HRESULT kesalahan standar.

Keterangan

Secara default, CComObjectRootEx::FinalConstruct hanya mengembalikan S_OK.

Ada keuntungan untuk melakukan inisialisasi daripada FinalConstruct konstruktor kelas Anda:

  • Anda tidak dapat mengembalikan kode status dari konstruktor, tetapi Anda dapat mengembalikan HRESULT dengan menggunakan FinalConstructnilai pengembalian. Saat objek kelas Anda dibuat menggunakan pabrik kelas standar yang disediakan oleh ATL, nilai pengembalian ini disebarkan kembali ke klien COM yang memungkinkan Anda memberi mereka informasi kesalahan terperinci.

  • Anda tidak dapat memanggil fungsi virtual melalui mekanisme fungsi virtual dari konstruktor kelas. Memanggil fungsi virtual dari konstruktor kelas menghasilkan panggilan yang diselesaikan secara statis ke fungsi seperti yang didefinisikan pada saat itu dalam hierarki warisan. Panggilan ke fungsi virtual murni mengakibatkan kesalahan linker.

    Kelas Anda bukan kelas yang paling turunan dalam hierarki warisan — kelas ini bergantung pada kelas turunan yang disediakan oleh ATL untuk menyediakan beberapa fungsionalitasnya. Ada kemungkinan besar bahwa inisialisasi Anda perlu menggunakan fitur yang disediakan oleh kelas tersebut (ini tentu benar ketika objek kelas Anda perlu menggabungkan objek lain), tetapi konstruktor di kelas Anda tidak memiliki cara untuk mengakses fitur-fitur tersebut. Kode konstruksi untuk kelas Anda dijalankan sebelum kelas yang paling turunan sepenuhnya dibangun.

    Namun, FinalConstruct dipanggil segera setelah kelas yang paling turunan sepenuhnya dibangun memungkinkan Anda untuk memanggil fungsi virtual dan menggunakan implementasi penghitungan referensi yang disediakan oleh ATL.

Contoh

Biasanya, ambil alih metode ini di kelas yang berasal dari CComObjectRootEx untuk membuat objek agregat apa pun. Contohnya:

class ATL_NO_VTABLE CMyAggObject :
   public CComObjectRootEx<CComSingleThreadModel>,
   public CComCoClass<CMyAggObject, &CLSID_MyAggObject>,
   public IDispatchImpl<IMyAggObject, &IID_IMyAggObject, &LIBID_NVC_ATL_COMLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
   DECLARE_GET_CONTROLLING_UNKNOWN()
   HRESULT FinalConstruct()
   {
      return CoCreateInstance(CLSID_MyCustomClass, GetControllingUnknown(), 
         CLSCTX_ALL, IID_IUnknown, (void**)&m_pMyCustomClass);
   }

   IMyCustomClass* m_pMyCustomClass;

   // Remainder of class declaration omitted.

Jika konstruksi gagal, Anda dapat mengembalikan kesalahan. Anda juga dapat menggunakan makro DECLARE_PROTECT_FINAL_CONSTRUCT untuk melindungi objek luar Anda agar tidak dihapus jika, selama pembuatan, objek agregat internal menaikkan jumlah referensi lalu mengurangi hitungan ke 0.

Berikut adalah cara umum untuk membuat agregat:

  • IUnknown Tambahkan penunjuk ke objek kelas Anda dan inisialisasi ke NULL di konstruktor.

  • Ambil alih FinalConstruct untuk membuat agregat.

  • Gunakan penunjuk yang IUnknown Anda tentukan sebagai parameter ke makro COM_INTERFACE_ENTRY_AGGREGATE .

  • Ambil alih FinalRelease untuk melepaskan IUnknown pointer.

CComObjectRootEx::FinalRelease

Anda dapat mengambil alih metode ini di kelas turunan Anda untuk melakukan pembersihan apa pun yang diperlukan untuk objek Anda.

void FinalRelease();

Keterangan

Secara default, CComObjectRootEx::FinalRelease tidak melakukan apa-apa.

Melakukan pembersihan lebih FinalRelease disukai untuk menambahkan kode ke destruktor kelas Anda karena objek masih sepenuhnya dibangun pada saat dipanggil FinalRelease . Ini memungkinkan Anda mengakses metode yang disediakan oleh kelas yang paling turunan dengan aman. Ini sangat penting untuk membebaskan objek agregat sebelum penghapusan.

CComObjectRootEx::InternalAddRef

Menaikkan jumlah referensi objek nonaggregated sebesar 1.

ULONG InternalAddRef();

Tampilkan Nilai

Nilai yang mungkin berguna untuk diagnostik dan pengujian.

Keterangan

Jika model utas multithread, InterlockedIncrement digunakan untuk mencegah lebih dari satu utas mengubah jumlah referensi secara bersamaan.

CComObjectRootEx::InternalQueryInterface

Mengambil penunjuk ke antarmuka yang diminta.

static HRESULT InternalQueryInterface(
    void* pThis,
    const _ATL_INTMAP_ENTRY* pEntries,
    REFIID iid,
    void** ppvObject);

Parameter

pThis
[di] Penunjuk ke objek yang berisi peta COM antarmuka yang diekspos ke QueryInterface.

pEntries
[di] Penunjuk ke _ATL_INTMAP_ENTRY struktur yang mengakses peta antarmuka yang tersedia.

iid
[di] GUID antarmuka yang diminta.

ppvObject
[out] Penunjuk ke penunjuk antarmuka yang ditentukan dalam iid, atau NULL jika antarmuka tidak ditemukan.

Tampilkan Nilai

Salah satu nilai HRESULT standar.

Keterangan

InternalQueryInterface hanya menangani antarmuka dalam tabel peta COM. Jika objek Anda diagregasi, InternalQueryInterface tidak mendelegasikan ke luar yang tidak diketahui. Anda dapat memasukkan antarmuka ke dalam tabel peta COM dengan makro COM_INTERFACE_ENTRY atau salah satu variannya.

CComObjectRootEx::InternalRelease

Mengurangi jumlah referensi objek nonaggregated sebesar 1.

ULONG InternalRelease();

Tampilkan Nilai

Dalam build non-debug dan debug, fungsi ini mengembalikan nilai yang mungkin berguna untuk diagnostik atau pengujian. Nilai pasti yang dikembalikan tergantung pada banyak faktor seperti sistem operasi yang digunakan, dan mungkin, atau mungkin tidak, menjadi jumlah referensi.

Keterangan

Jika model utas multithread, InterlockedDecrement digunakan untuk mencegah lebih dari satu utas mengubah jumlah referensi secara bersamaan.

CComObjectRootEx::Lock

Jika model utas multithreaded, metode ini memanggil fungsi API Win32 EnterCriticalSection, yang menunggu hingga utas dapat mengambil kepemilikan objek bagian penting yang diperoleh melalui anggota data privat.

void Lock();

Keterangan

Ketika kode yang dilindungi selesai dieksekusi, utas harus memanggil Unlock untuk merilis kepemilikan bagian penting.

Jika model utas berulir tunggal, metode ini tidak melakukan apa pun.

CComObjectRootEx::m_dwRef

Bagian dari serikat yang mengakses empat byte memori.

long m_dwRef;

Keterangan

Dengan m_pOuterUnknown, bagian dari serikat:

union {
    long m_dwRef;
    IUnknown* m_pOuterUnknown;
};

Jika objek tidak diagregasi, jumlah referensi yang diakses oleh AddRef dan Release disimpan di m_dwRef. Jika objek diagregasi, penunjuk ke luar yang tidak diketahui disimpan di m_pOuterUnknown.

CComObjectRootEx::m_pOuterUnknown

Bagian dari serikat yang mengakses empat byte memori.

IUnknown*
    m_pOuterUnknown;

Keterangan

Dengan m_dwRef, bagian dari serikat:

union {
    long m_dwRef;
    IUnknown* m_pOuterUnknown;
};

Jika objek diagregasi, penunjuk ke luar yang tidak diketahui disimpan di m_pOuterUnknown. Jika objek tidak diagregasi, jumlah referensi yang diakses oleh AddRef dan Release disimpan dalam m_dwRef.

CComObjectRootEx::ObjectMain

Untuk setiap kelas yang tercantum dalam peta objek, fungsi ini dipanggil sekali ketika modul diinisialisasi, dan sekali lagi ketika dihentikan.

static void WINAPI ObjectMain(bool bStarting);

Parameter

bStarting
[out] Nilainya TRUE jika kelas sedang diinisialisasi; jika tidak FALSE.

Keterangan

Nilai parameter bStarting menunjukkan apakah modul sedang diinisialisasi atau dihentikan. Implementasi ObjectMain default tidak melakukan apa-apa, tetapi Anda dapat mengambil alih fungsi ini di kelas Anda untuk menginisialisasi atau membersihkan sumber daya yang ingin Anda alokasikan untuk kelas. Perhatikan bahwa ObjectMain dipanggil sebelum instans kelas diminta.

ObjectMain dipanggil dari titik masuk DLL, sehingga jenis operasi yang dapat dilakukan fungsi titik masuk dibatasi. Untuk informasi selengkapnya tentang pembatasan ini, lihat DLL dan perilaku pustaka run-time Visual C++ dan DllMain.

Contoh

class ATL_NO_VTABLE CMyApp :
   public CComObjectRootEx<CComSingleThreadModel>,
   public CComCoClass<CMyApp, &CLSID_MyApp>,
   public IMyApp
{
public:
   CMyApp()
   {
   }

   static void WINAPI ObjectMain(bool bStarting)
   {
      if (bStarting)
         ;// Perform custom initialization routines
      else
         ;// Perform custom termination routines
   }

   // Remainder of class declaration omitted.

CComObjectRootEx::OuterAddRef

Menaikkan jumlah referensi dari luar yang tidak diketahui dari agregasi.

ULONG OuterAddRef();

Tampilkan Nilai

Nilai yang mungkin berguna untuk diagnostik dan pengujian.

CComObjectRootEx::OuterQueryInterface

Mengambil penunjuk tidak langsung ke antarmuka yang diminta.

HRESULT OuterQueryInterface(REFIID iid, void** ppvObject);

Parameter

iid
[di] GUID antarmuka yang diminta.

ppvObject
[out] Penunjuk ke penunjuk antarmuka yang ditentukan dalam iid, atau NULL jika agregasi tidak mendukung antarmuka.

Tampilkan Nilai

Salah satu nilai HRESULT standar.

CComObjectRootEx::OuterRelease

Mengurangi jumlah referensi luar yang tidak diketahui dari agregasi.

ULONG OuterRelease();

Tampilkan Nilai

Dalam build non-debug, selalu mengembalikan 0. Dalam build debug, mengembalikan nilai yang mungkin berguna untuk diagnostik atau pengujian.

CComObjectRootEx::Unlock

Jika model utas multithreaded, metode ini memanggil fungsi API Win32 LeaveCriticalSection, yang merilis kepemilikan objek bagian penting yang diperoleh melalui anggota data privat.

void Unlock();

Keterangan

Untuk mendapatkan kepemilikan, utas harus memanggil Lock. Setiap panggilan untuk Lock memerlukan panggilan yang sesuai untuk Unlock merilis kepemilikan bagian penting.

Jika model utas berulir tunggal, metode ini tidak melakukan apa pun.

Lihat juga

Kelas CComAggObject
Kelas CComObject
Kelas CComPolyObject
Gambaran Umum Kelas