Pustaka COM

Setiap proses yang menggunakan COM harus menginisialisasi dan tidak menginisialisasi pustaka COM. Selain menjadi spesifikasi, COM juga menerapkan beberapa layanan penting di pustaka ini. Disediakan sebagai sekumpulan DLL dan EXE (terutama Ole32.dll dan Rpcss.exe) di Microsoft Windows, pustaka COM mencakup hal-hal berikut:

  • Sejumlah kecil fungsi dasar yang memfasilitasi pembuatan aplikasi COM, baik klien maupun server. Untuk klien, COM menyediakan fungsi dasar untuk membuat objek. Untuk server, COM menyediakan sarana untuk mengekspos objek mereka.

  • Layanan pencari implementasi di mana COM menentukan, dari pengidentifikasi kelas unik (CLSID), server mana yang mengimplementasikan kelas tersebut dan di mana server tersebut berada. Layanan ini mencakup dukungan untuk lapisan abstraksi, biasanya berupa registri sistem, antara identitas kelas objek dan pengemasan implementasi, sehingga klien tidak bergantung pada pengemasan tersebut, yang dapat berubah di masa mendatang.

  • Prosedur jarak jauh transparan memanggil ketika objek berjalan di server lokal atau jarak jauh.

  • Mekanisme standar untuk memungkinkan aplikasi mengontrol bagaimana memori dialokasikan dalam prosesnya, terutama memori yang perlu diteruskan antara objek yang bekerja sama sehingga dapat dibebaskan dengan benar.

Untuk menggunakan layanan COM dasar, semua utas COM eksekusi di klien dan server di luar proses harus memanggil fungsi CoInitialize atau CoInitializeEx sebelum memanggil fungsi COM lainnya kecuali panggilan alokasi memori. CoInitializeEx menggantikan fungsi yang lain dengan menambahkan parameter yang memungkinkan Anda menentukan model threading untuk utas: baik apartment-threaded maupun free-threaded. Pemanggilan CoInitialize hanya menetapkan model threading menjadi apartemen-threaded.

Aplikasi dokumen gabungan OLE memanggil fungsi OleInitialize , yang memanggil CoInitializeEx dan juga melakukan beberapa inisialisasi yang diperlukan untuk dokumen gabungan. Oleh karena itu, utas yang memanggil OleInitialize tidak dapat di-utas bebas. Untuk informasi tentang utas di klien dan server, lihat Proses, Utas, dan Apartemen.

Server dalam-proses tidak memanggil fungsi inisialisasi karena dimuat ke dalam proses yang sudah memanggil fungsi tersebut. Akibatnya, server dalam proses harus mengatur model threading mereka di registri di bawah kunci InprocServer32 . Untuk informasi terperinci tentang masalah utas pada server in-proses, lihat Masalah Utas pada Server In-Proses.

Penting juga untuk tidak menginisialisasi pustaka. Untuk setiap panggilan ke CoInitialize atau CoInitializeEx, harus ada panggilan yang sesuai untuk CoUninitialize. Untuk setiap panggilan ke OleInitialize, harus ada panggilan yang sesuai ke OleUninitialize.

Server dalam proses dapat mengasumsikan bahwa proses yang dimuat telah melakukan langkah-langkah ini.

Important

Setiap utas yang menggunakan COM harus memanggil CoInitializeEx sebelum memanggil fungsi COM lainnya. Ini adalah kesalahan inisialisasi COM yang paling umum — memanggil CoCreateInstance atau API COM lainnya pada utas yang belum diinisialisasi akan gagal dengan CO_E_NOTINITIALIZED (0x800401F0).

Tip

Pola yang direkomendasikan - gunakan penjaga RAII untuk memastikan uninitialisasi:

#include <wil/com.h>  // Windows Implementation Libraries

// wil::unique_couninitialize_call calls CoUninitialize automatically on scope exit
auto comInit = wil::CoInitializeEx(COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

// ... use COM — CoUninitialize is called when comInit goes out of scope,
//     even if an exception is thrown ...

Jika wil tidak tersedia, panggil CoUninitialize() secara manual — setiap pemanggilan CoInitializeEx yang berhasil harus dipasangkan dengan tepat satu pemanggilan CoUninitialize:

HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (FAILED(hr)) return hr;

// ... use COM ...

CoUninitialize();

Important

Kesalahan umum:

  • Memanggil fungsi COM tanpa menginisialisasi COM pada utas saat ini.
  • Panggilan yang CoInitializeEx / CoUninitialize tidak cocok (setiap init yang berhasil membutuhkan persis satu uninit).
  • Mencampur model apartment dalam thread yang sama (memanggil CoInitializeEx dengan model yang berbeda dari panggilan sukses sebelumnya akan mengembalikan RPC_E_CHANGED_MODE).

Model Objek Komponen (Component Object Model)