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
, OuterAddRef
dan 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
, InternalAddRef
dan 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
FinalConstruct
nilai 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 melepaskanIUnknown
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