Bagikan melalui


DLL ekstensi MFC

DLL ekstensi MFC adalah DLL yang biasanya menerapkan kelas yang dapat digunakan kembali yang berasal dari kelas Pustaka Kelas Microsoft Foundation yang ada.

DLL ekstensi MFC memiliki fitur dan persyaratan berikut:

  • Klien yang dapat dieksekusi harus merupakan aplikasi MFC yang dikompilasi dengan _AFXDLL yang ditentukan.

  • DLL ekstensi MFC juga dapat digunakan oleh DLL MFC reguler yang secara dinamis ditautkan ke MFC.

  • DLL ekstensi MFC harus dikompilasi dengan _AFXEXT yang ditentukan. Ini memaksa _AFXDLL untuk juga didefinisikan dan memastikan bahwa deklarasi yang tepat ditarik dari file header MFC. Ini juga memastikan bahwa AFX_EXT_CLASS didefinisikan sebagai __declspec(dllexport) saat membangun DLL, yang diperlukan jika Anda menggunakan makro ini untuk mendeklarasikan kelas di DLL ekstensi MFC Anda.

  • DLL ekstensi MFC tidak boleh membuat instans kelas yang berasal dari CWinApp, tetapi harus mengandalkan aplikasi klien (atau DLL) untuk menyediakan objek ini.

  • Namun, DLL ekstensi MFC harus menyediakan DllMain fungsi dan melakukan inisialisasi yang diperlukan di sana.

DLL ekstensi dibangun menggunakan MFC versi pustaka tautan dinamis (juga dikenal sebagai versi bersama MFC). Hanya executable MFC (baik aplikasi atau DLL MFC reguler) yang dibangun dengan versi bersama MFC yang dapat menggunakan DLL ekstensi MFC. Aplikasi klien dan DLL ekstensi MFC harus menggunakan versi MFCx0.dll yang sama. Dengan DLL ekstensi MFC, Anda dapat memperoleh kelas kustom baru dari MFC dan kemudian menawarkan versi MFC yang diperluas ini ke aplikasi yang memanggil DLL Anda.

DLL ekstensi juga dapat digunakan untuk meneruskan objek turunan MFC antara aplikasi dan DLL. Fungsi anggota yang terkait dengan objek yang diteruskan ada di modul tempat objek dibuat. Karena fungsi-fungsi ini diekspor dengan benar saat menggunakan MFC versi DLL bersama, Anda dapat dengan bebas meneruskan penunjuk objek turunan MFC atau MFC antara aplikasi dan DLL ekstensi MFC yang dimuatnya.

DLL ekstensi MFC menggunakan MFC versi bersama dengan cara yang sama seperti aplikasi menggunakan MFC versi DLL bersama, dengan beberapa pertimbangan tambahan:

  • Ini tidak memiliki CWinAppobjek -turunan. Ini harus bekerja dengan CWinAppobjek -turunan dari aplikasi klien. Ini berarti bahwa aplikasi klien memiliki pompa pesan utama, perulangan diam, dan sebagainya.

  • Ini memanggil AfxInitExtensionModule dalam fungsinya DllMain . Nilai pengembalian fungsi ini harus diperiksa. Jika nilai nol dikembalikan dari AfxInitExtensionModule, kembalikan 0 dari fungsi Anda DllMain .

  • Ini membuat objek CDynLinkLibrary selama inisialisasi jika DLL ekstensi MFC ingin mengekspor CRuntimeClass objek atau sumber daya ke aplikasi.

Sebelum MFC versi 4.0, jenis DLL ini disebut AFXDLL. AFXDLL mengacu pada _AFXDLL simbol pra-prosesor yang ditentukan saat membangun DLL.

Pustaka impor untuk versi bersama MFC dinamai sesuai dengan konvensi yang dijelaskan dalam Konvensi penamaan untuk DLL MFC. Visual Studio menyediakan versi bawaan DLL MFC, ditambah sejumlah DLL non-MFC yang dapat Anda gunakan dan distribusikan dengan aplikasi Anda. Ini didokumenkan dalam Redist.txt, yang diinstal ke folder Program Files\Microsoft Visual Studio.

Jika Anda mengekspor menggunakan file .def, letakkan kode berikut di awal dan akhir file header Anda:

#undef AFX_DATA
#define AFX_DATA AFX_EXT_DATA
// <body of your header file>
#undef AFX_DATA
#define AFX_DATA

Keempat baris ini memastikan bahwa kode Anda dikompilasi dengan benar untuk DLL ekstensi MFC. Meninggalkan empat baris ini dapat menyebabkan DLL Anda salah mengkompilasi atau menautkan.

Jika Anda perlu meneruskan penunjuk objek turunan MFC atau MFC ke atau dari DLL MFC, DLL harus menjadi DLL ekstensi MFC. Fungsi anggota yang terkait dengan objek yang diteruskan ada di modul tempat objek dibuat. Karena fungsi-fungsi ini diekspor dengan benar saat menggunakan MFC versi DLL bersama, Anda dapat dengan bebas meneruskan penunjuk objek turunan MFC atau MFC antara aplikasi dan DLL ekstensi MFC yang dimuatnya.

Karena masalah mangling dan ekspor nama C++, daftar ekspor dari DLL ekstensi MFC mungkin berbeda antara versi debug dan ritel dari DLL dan DLL yang sama untuk platform yang berbeda. MFCx0.dll ritel memiliki sekitar 2.000 titik masuk yang diekspor; debug MFCx0D.dll memiliki sekitar 3.000 titik masuk yang diekspor.

Manajemen Memori

MFCx0.dll dan semua DLL ekstensi MFC yang dimuat ke dalam ruang alamat aplikasi klien menggunakan alokator memori yang sama, pemuatan sumber daya, dan status global MFC lainnya seolah-olah mereka berada dalam aplikasi yang sama. Ini signifikan karena pustaka DLL non-MFC dan DLL MFC reguler melakukan hal yang berlawanan dan memiliki setiap DLL yang mengalokasikan keluar dari kumpulan memorinya sendiri.

Jika DLL ekstensi MFC mengalokasikan memori, memori tersebut dapat dengan bebas melakukan intermix dengan objek lain yang dialokasikan aplikasi. Selain itu, jika aplikasi yang secara dinamis terhubung ke MFC gagal, perlindungan sistem operasi mempertahankan integritas aplikasi MFC lainnya yang berbagi DLL.

Demikian pula status MFC global lainnya, seperti file yang dapat dieksekusi saat ini untuk memuat sumber daya, juga dibagikan antara aplikasi klien dan semua DLL ekstensi MFC serta MFCx0.dll itu sendiri.

Berbagi Sumber Daya dan Kelas

Mengekspor sumber daya dilakukan melalui daftar sumber daya. Setiap aplikasi berisi daftar objek CDynLinkLibrary yang ditautkan secara senyap. Saat mencari sumber daya, sebagian besar implementasi MFC standar yang memuat sumber daya melihat terlebih dahulu modul sumber daya saat ini (AfxGetResourceHandle) dan jika sumber daya tidak ditemukan berjalan daftar objek CDynLinkLibrary yang mencoba memuat sumber daya yang diminta.

Berjalan dalam daftar memiliki kelemahan yang sedikit lebih lambat dan memerlukan pengelolaan rentang ID sumber daya. Ini memiliki keuntungan bahwa aplikasi klien yang menautkan ke beberapa DLL ekstensi MFC dapat menggunakan sumber daya yang disediakan DLL tanpa harus menentukan handel instans DLL. AfxFindResourceHandle adalah API yang digunakan untuk berjalan di daftar sumber daya untuk mencari kecocokan tertentu. Dibutuhkan nama dan jenis sumber daya dan mengembalikan handel sumber daya tempat pertama kali ditemukan (atau NULL).

Jika Anda tidak ingin memanjat daftar dan hanya memuat sumber daya dari tempat tertentu, gunakan fungsi AfxGetResourceHandle dan AfxSetResourceHandle untuk menyimpan handel lama dan mengatur handel baru. Pastikan untuk memulihkan handel sumber daya lama sebelum Anda kembali ke aplikasi klien. Untuk contoh penggunaan pendekatan ini untuk memuat menu secara eksplisit, lihat Testdll2 .cpp dalam sampel MFC DLLHUSK.

Pembuatan dinamis objek MFC yang diberi nama MFC serupa. Mekanisme deserialisasi objek MFC harus memiliki semua CRuntimeClass objek yang terdaftar sehingga dapat membangun kembali dengan membuat objek C++ secara dinamis dari jenis yang diperlukan berdasarkan apa yang disimpan sebelumnya.

Dalam kasus sampel MFC DLLHUSK, daftar terlihat seperti:

head ->   DLLHUSK.EXE   - or -   DLLHUSK.EXE
               |                      |
          TESTDLL2.DLL           TESTDLL2.DLL
               |                      |
          TESTDLL1.DLL           TESTDLL1.DLL
               |                      |
           MFCOxxD.DLL                |
               |                      |
           MFCDxxD.DLL                |
               |                      |
            MFCxxD.DLL            MFCxx.DLL

di mana xx adalah nomor versi; misalnya, 42 mewakili versi 4.2.

MFCxx.dll biasanya terakhir pada daftar sumber daya dan kelas. MFCxx.dll mencakup semua sumber daya MFC standar, termasuk string prompt untuk semua ID perintah standar. Menempatkannya di akhir daftar memungkinkan DLL dan aplikasi klien itu sendiri untuk tidak memiliki salinan sumber daya MFC standar mereka sendiri, tetapi untuk mengandalkan sumber daya bersama di MFCxx.dll sebagai gantinya.

Menggabungkan sumber daya dan nama kelas semua DLL ke dalam ruang nama aplikasi klien memiliki kerugian yang mengharuskan Anda untuk berhati-hati dengan ID atau nama apa yang Anda pilih.

Sampel DLLHUSK mengelola ruang nama sumber daya bersama dengan menggunakan beberapa file header.

Jika DLL ekstensi MFC Anda perlu mempertahankan data tambahan untuk setiap aplikasi, Anda dapat memperoleh kelas baru dari CDynLinkLibrary dan membuatnya di DllMain. Saat berjalan, DLL dapat memeriksa daftar objek CDynLinkLibrary aplikasi saat ini untuk menemukan yang untuk DLL ekstensi MFC tertentu.

Apa yang ingin Anda lakukan?

Apa yang ingin Anda ketahui lebih lanjut?

Lihat juga

Membuat C/C++ DLL di Visual Studio