Bagikan melalui


Menggunakan DLL ekstensi MFC Database, OLE, dan Soket di DLL MFC reguler

Saat menggunakan DLL ekstensi MFC dari DLL MFC reguler, jika DLL ekstensi MFC tidak dikabeli ke dalam CDynLinkLibrary rantai objek DLL MFC reguler, Anda mungkin mengalami satu atau beberapa masalah terkait. Karena versi debug MFC Database, OLE, dan Sockets mendukung DLL diimplementasikan sebagai DLL ekstensi MFC, Anda mungkin melihat masalah serupa jika Anda menggunakan fitur MFC ini, bahkan jika Anda tidak secara eksplisit menggunakan DLL ekstensi MFC Anda sendiri. Beberapa gejalanya adalah:

  • Saat mencoba mendeserialisasi objek dari jenis kelas yang ditentukan dalam DLL ekstensi MFC, pesan "Peringatan: Tidak dapat memuat CYourClass dari arsip. Kelas tidak ditentukan." muncul di jendela debug TRACE dan objek gagal diserialisasikan.

  • Pengecualian yang menunjukkan kelas buruk mungkin dilemparkan.

  • Sumber daya yang disimpan di DLL ekstensi MFC gagal dimuat karena AfxFindResourceHandle mengembalikan NULL atau handel sumber daya yang salah.

  • DllGetClassObject, , DllCanUnloadNowdan UpdateRegistryfungsi COleObjectFactory anggota , Revoke, RevokeAll, dan RegisterAll gagal menemukan pabrik kelas yang ditentukan dalam DLL ekstensi MFC.

  • AfxDoForAllClasses tidak berfungsi untuk kelas apa pun di DLL ekstensi MFC.

  • Database MFC standar, soket, atau sumber daya OLE gagal dimuat. Misalnya, AfxLoadString(AFX_IDP_SQL_CONNECT_FAIL) mengembalikan string kosong, bahkan ketika DLL MFC reguler menggunakan kelas Database MFC dengan benar.

Solusi untuk masalah ini adalah membuat dan mengekspor fungsi inisialisasi CDynLinkLibrary di DLL ekstensi MFC yang membuat objek. Panggil fungsi inisialisasi ini persis sekali dari setiap DLL MFC reguler yang menggunakan DLL ekstensi MFC.

Dukungan Soket MFC OLE, MFC Database (atau DAO), atau MFC

Jika Anda menggunakan dukungan MFC OLE, MFC Database (atau DAO), atau MFC Sockets di DLL MFC reguler Anda, masing-masing, DLL MFCOxxD.dllekstensi MFC debug MFC, , , MFCDxxD.dlldan MFCNxxD.dll (di mana xx adalah nomor versi) ditautkan secara otomatis. Panggil fungsi inisialisasi yang telah ditentukan sebelumnya untuk setiap DLL yang Anda gunakan:

  • Untuk dukungan database, tambahkan panggilan ke AfxDbInitModule DLL MFC reguler Anda dalam fungsinya CWinApp::InitInstance . Pastikan panggilan ini terjadi sebelum panggilan kelas dasar atau kode tambahan apa pun yang mengakses MFCDxxD.dll. Fungsi ini tidak mengambil parameter dan mengembalikan void.

  • Untuk dukungan OLE, tambahkan panggilan ke AfxOleInitModule DLL MFC reguler Anda, fungsinya CWinApp::InitInstance . Fungsi memanggil COleControlModule::InitInstance AfxOleInitModule sudah, jadi jika Anda membangun kontrol OLE dan menggunakan COleControlModule, Anda tidak boleh menambahkan panggilan ini ke AfxOleInitModule.

  • Untuk dukungan Soket, tambahkan panggilan ke AfxNetInitModule DLL MFC reguler Anda di CWinApp::InitInstance.

Rilis build DLL dan aplikasi MFC tidak menggunakan DLL terpisah untuk dukungan database, soket, atau OLE. Namun, aman untuk memanggil fungsi inisialisasi ini dalam mode rilis.

Objek CDynLinkLibrary

Selama setiap operasi yang disebutkan di awal artikel ini, MFC perlu mencari nilai atau objek tertentu. Misalnya, selama deserialisasi, MFC perlu mencari semua kelas run-time yang saat ini tersedia untuk mencocokkan objek dalam arsip dengan kelas run-time yang tepat.

Sebagai bagian dari pencarian ini, MFC memindai semua DLL ekstensi MFC yang digunakan dengan menjalankan rantai CDynLinkLibrary objek. CDynLinkLibrary objek melekat secara otomatis ke rantai selama konstruksinya dan dibuat oleh setiap DLL ekstensi MFC pada gilirannya selama inisialisasi. Setiap modul (aplikasi atau DLL MFC reguler) memiliki rantai CDynLinkLibrary objeknya sendiri.

Agar DLL ekstensi MFC tersambung ke rantai CDynLinkLibrary , dll harus membuat CDynLinkLibrary objek dalam konteks setiap modul yang menggunakan DLL ekstensi MFC. Untuk menggunakan DLL ekstensi MFC di DLL MFC reguler, DLL ekstensi harus menyediakan fungsi inisialisasi CDynLinkLibrary yang diekspor yang membuat objek. Setiap DLL MFC reguler yang menggunakan DLL ekstensi MFC harus memanggil fungsi inisialisasi yang diekspor.

Jika Anda hanya akan menggunakan DLL ekstensi MFC dari aplikasi MFC, dan tidak pernah dari DLL MFC biasa, maka cukup untuk membuat CDynLinkLibrary objek dalam fungsi DLL DllMain ekstensi MFC. Inilah yang dilakukan kode DLL ekstensi MFC DLL MFC. Saat memuat DLL ekstensi MFC secara implisit, DllMain memuat dan menjalankan sebelum aplikasi dimulai. Setiap CDynLinkLibrary kreasi dikabeli ke dalam rantai default yang disediakan DLL MFC untuk aplikasi MFC.

Adalah ide yang buruk untuk memiliki beberapa CDynLinkLibrary objek dari satu DLL ekstensi MFC dalam satu rantai apa pun. Ini terutama benar jika DLL ekstensi MFC mungkin dibongkar secara dinamis dari memori. Jangan panggil fungsi inisialisasi lebih dari sekali dari satu modul.

Kode Sampel

Kode sampel ini mengasumsikan bahwa DLL MFC reguler secara implisit menautkan ke DLL ekstensi MFC. Untuk menautkan secara implisit, tautkan ke pustaka impor (file LIB) dll ekstensi MFC saat Anda membangun DLL MFC reguler.

Baris berikut harus berada di sumber DLL ekstensi MFC:

// YourExtDLL.cpp:

// standard MFC extension DLL routines
#include "afxdllx.h"

static AFX_EXTENSION_MODULE extensionDLL;

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        // MFC extension DLL one-time initialization
        if (!AfxInitExtensionModule(extensionDLL, hInstance))
           return 0;
    }
    return 1;   // ok
}

// Exported DLL initialization is run in context of
// application or regular MFC DLL
extern "C" void WINAPI InitYourExtDLL()
{
    // create a new CDynLinkLibrary for this app
    new CDynLinkLibrary(extensionDLL);

    // add other initialization here
}

Pastikan untuk mengekspor fungsi InitYourExtDLL . Anda dapat menggunakan __declspec(dllexport), atau mengekspornya dalam file DEF untuk DLL Anda, seperti yang ditunjukkan di sini:

// YourExtDLL.Def:
LIBRARY      YOUREXTDLL
CODE         PRELOAD MOVEABLE DISCARDABLE
DATA         PRELOAD SINGLE
EXPORTS
    InitYourExtDLL

Tambahkan panggilan ke InitInstance anggota CWinAppobjek -turunan di setiap DLL MFC reguler menggunakan DLL ekstensi MFC:

// YourRegularDLL.cpp:

class CYourRegularDLL : public CWinApp
{
public:
    virtual BOOL InitInstance(); // Initialization
    virtual int ExitInstance();  // Termination

    // nothing special for the constructor
    CYourRegularDLL(LPCTSTR pszAppName) : CWinApp(pszAppName) { }
};

BOOL CYourRegularDLL::InitInstance()
{
    // any DLL initialization goes here
    TRACE0("YOUR regular MFC DLL initializing\n");

    // wire any MFC extension DLLs into CDynLinkLibrary chain
    InitYourExtDLL();

    return TRUE;
}

Apa yang ingin Anda lakukan?

Apa yang ingin Anda ketahui lebih lanjut?

Lihat juga

DLL ekstensi MFC