Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Ao usar uma DLL de extensão MFC de uma DLL MFC regular, se a DLL de extensão MFC não estiver conectada CDynLinkLibrary à cadeia de objetos da DLL MFC regular, você poderá ter um ou mais problemas relacionados. Como as versões de depuração do banco de dados MFC, OLE e DLLs de suporte a soquetes são implementadas como DLLs de extensão MFC, você pode ver problemas semelhantes se estiver usando esses recursos MFC, mesmo se você não estiver usando explicitamente qualquer uma de suas próprias DLLs de extensão MFC. Alguns sintomas são:
Ao tentar desserializar um objeto de um tipo de classe definida na extensão MFC DLL, a mensagem "Aviso: Não é possível carregar CYourClass do arquivo. Class not defined." aparece na janela de depuração TRACE e o objeto não consegue serializar.
Uma exceção indicando classe ruim pode ser lançada.
Os recursos armazenados na DLL de extensão MFC não são carregados porque
AfxFindResourceHandleretornaNULLou um identificador de recurso incorreto.DllGetClassObject,DllCanUnloadNowe as funções membroUpdateRegistry,Revoke,RevokeAll, eRegisterAlldeCOleObjectFactoryfalham ao localizar uma fábrica de classes definida numa DLL de extensão MFC.AfxDoForAllClassesnão funciona para nenhuma classe na DLL de extensão MFC.Banco de dados MFC padrão, soquetes ou recursos OLE não são carregados. Por exemplo,
AfxLoadString(AFX_IDP_SQL_CONNECT_FAIL)retorna uma cadeia de caracteres vazia, mesmo quando a DLL MFC regular está usando corretamente as classes de banco de dados MFC.
A solução para esses problemas é criar e exportar uma função de inicialização na DLL de extensão MFC que cria um CDynLinkLibrary objeto. Chame esta função de inicialização exatamente uma vez em cada DLL MFC regular que utiliza a DLL de extensão MFC.
MFC OLE, MFC Database (ou DAO) ou Suporte de Sockets MFC
Se estiver a utilizar suporte para MFC OLE, MFC Database (ou DAO) ou MFC Sockets na sua DLL MFC regular, as DLLs de extensão MFC de depuração MFCOxxD.dll, MFCDxxD.dll e MFCNxxD.dll (onde xx é o número da versão) serão vinculadas automaticamente. Chame uma função de inicialização predefinida para cada uma das DLLs que você está usando:
Para suporte de banco de dados, adicione uma chamada para
AfxDbInitModulena funçãoCWinApp::InitInstanceda sua DLL MFC regular. Certifique-se de que esta chamada ocorre antes de qualquer chamada de classe base ou qualquer código adicionado que aceda aoMFCDxxD.dll. Esta função não usa parâmetros e retornavoid.Para o suporte do OLE, adicione uma chamada para o seu DLL regular do MFC na sua função
AfxOleInitModule. A funçãoCOleControlModule::InitInstancejá chamaAfxOleInitModule, portanto, se estiver a criar um controlo OLE e usarCOleControlModule, não deve adicionar esta chamada aAfxOleInitModule.Para suporte a Sockets, adicione uma chamada para
AfxNetInitModulena sua DLL MFC regular emCWinApp::InitInstance.
Compilações de lançamento de DLLs MFC e aplicações não utilizam DLLs separadas para suporte a base de dados, sockets ou OLE. No entanto, é seguro chamar essas funções de inicialização no modo de lançamento.
Objetos CDynLinkLibrary
Durante cada operação mencionada no início deste artigo, o MFC precisa procurar um determinado valor ou objeto. Por exemplo, durante a desserialização, o MFC precisa pesquisar todas as classes de execução atualmente disponíveis para associar objetos no arquivo com a sua classe de execução adequada.
Como parte dessas pesquisas, o MFC examina todas as DLLs de extensão MFC em uso, percorrendo uma cadeia de CDynLinkLibrary objetos.
CDynLinkLibrary os objetos se conectam automaticamente a uma cadeia durante sua construção e são criados por cada DLL de extensão MFC por sua vez durante a inicialização. Cada módulo (aplicativo ou DLL MFC regular) tem sua própria cadeia de CDynLinkLibrary objetos.
Para que uma DLL de extensão MFC seja conectada a uma CDynLinkLibrary cadeia, ela deve criar um CDynLinkLibrary objeto no contexto de cada módulo que usa a DLL de extensão MFC. Para usar uma DLL de extensão MFC em DLLs MFC regulares, a DLL de extensão deve fornecer uma função de inicialização exportada que cria um CDynLinkLibrary objeto. Cada DLL MFC regular que usa a DLL de extensão MFC deve chamar a função de inicialização exportada.
Caso utilize apenas uma DLL de extensão MFC a partir de uma aplicação MFC, e nunca a partir de uma DLL MFC regular, então é suficiente criar o objeto CDynLinkLibrary na função DllMain da DLL de extensão MFC. É o que o código da extensão DLL do Assistente MFC faz. Ao carregar uma DLL de extensão MFC implicitamente, DllMain carrega e executa antes que o aplicativo seja iniciado. Todas CDynLinkLibrary as criações são conectadas em uma cadeia padrão que a DLL MFC reserva para um aplicativo MFC.
É uma má ideia ter vários CDynLinkLibrary objetos de uma DLL de extensão MFC em uma única cadeia. É especialmente verdadeiro se a DLL da extensão MFC pode ser descarregada dinamicamente da memória. Não chame a função de inicialização mais de uma vez a partir de qualquer módulo.
Código de Exemplo
Este código de exemplo pressupõe que a DLL MFC regular implicitamente se vincula à DLL de extensão MFC. Para vincular implicitamente, vincule à biblioteca de importação (ficheiro LIB) da DLL de extensão MFC ao criar a DLL MFC regular.
As seguintes linhas devem estar no código-fonte da DLL de extensão 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
}
Certifique-se de exportar a função InitYourExtDLL . Você pode usar __declspec(dllexport)ou exportá-lo no arquivo DEF para sua DLL, conforme mostrado aqui:
// YourExtDLL.Def:
LIBRARY YOUREXTDLL
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD SINGLE
EXPORTS
InitYourExtDLL
Adicione uma chamada para o membro do objeto derivado InitInstance em cada DLL MFC regular, usando a DLL de extensão 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;
}