Usando o banco de dados OLE e DLLs de extensão do Sockets em DLLs normais
Ao usar uma extensão DLL por uma DLL regular, se a extensão DLL não conectada na CDynLinkLibrary objeto cadeia da DLL normal, você pode executar em um ou mais de um conjunto de problemas relacionados.Como as versões de depuração de banco de dados MFC, OLE e Sockets suportam DLLs são implementadas como DLLs de extensão, você pode ver problemas semelhantes, se você estiver usando esses MFC recursos, mesmo se você não estiver explicitamente usando qualquer uma das suas próprias DLLs de extensão.Alguns sintomas são:
Ao tentar desserializar um objeto de um tipo de classe definido na extensão DLL, a mensagem "Aviso: não é possível carregar CYourClass de arquivamento.Classe não definida."aparece na janela de rastreamento de depuração e não consegue serializar o objeto.
Pode ser lançada uma exceção indicando classe incorreta.
Recursos armazenados na extensão DLL falham ao carregar porque AfxFindResourceHandle retorna Nulo ou um identificador de recurso incorreto.
DllGetClassObject, DllCanUnloadNowe o UpdateRegistry, Revoke, RevokeAll, e RegisterAll funções de membro COleObjectFactory falhar localizar uma fábrica de classes definida na DLL de extensão.
AfxDoForAllClassesnão funciona para todas as classes na DLL de extensão.
Banco de dados padrão do MFC, soquetes ou recursos OLE falham ao carregar.Por exemplo, AfxLoadString(AFX_IDP_SQL_CONNECT_FAIL) retorna uma seqüência vazia, mesmo quando a DLL regular é corretamente usando as classes de banco de dados MFC.
A solução para esses problemas é criar e exportar uma função de inicialização na extensão DLL cria um CDynLinkLibrary objeto.Chame essa função de inicialização exatamente uma vez de cada DLL comum que usa a extensão DLL.
MFC OLE, o banco de dados MFC (ou DAO), ou o suporte a MFC Sockets
Se você estiver usando qualquer OLE do MFC, banco de dados MFC (ou DAO), ou MFC Sockets suporte na sua DLL regular, respectivamente, a extensão de depuração do MFC DLLs MFCOxxD.dll, MFCDxxD.dll e MFCNxxD.dll (onde xx é o número de versão) são vinculados automaticamente.Você deve chamar uma função de inicialização predefinidas para cada uma dessas DLLs que você está usando.
Para suporte de banco de dados, adicione uma chamada para AfxDbInitModule a sua DLL regulares CWinApp::InitInstance função.Verifique se essa chamada ocorre antes de qualquer chamada de classe base ou nenhum adicionado o código que acessa o MFCDxxD.dll.Esta função sem parâmetros e retorna void.
Para obter suporte OLE, adicionar uma chamada para AfxOleInitModule a sua DLL regulares CWinApp::InitInstance.Observe que o COleControlModule InitInstance chamadas de função AfxOleInitModule , portanto, se você estiver criando um controle OLE e estiver usando COleControlModule, você não deve adicionar esta chamada para AfxOleInitModule.
Para suporte de Sockets, adicionar uma chamada para AfxNetInitModule a sua DLL regulares CWinApp::InitInstance.
Observe que libere compilações do MFC DLLs e aplicativos não usarem DLLs separadas para o banco de dados, soquetes, ou suporte a OLE.No entanto, é seguro chamar essas funções de inicialização no modo de versão.
Objetos CDynLinkLibrary
Durante cada uma das operações mencionadas no início deste tópico, MFC precisa pesquisar para um objeto ou o valor desejado.Por exemplo, durante a desserialização, MFC precisa pesquisar todas as classes de tempo de execução disponíveis atualmente para corresponder aos objetos no arquivamento com sua classe de tempo de execução adequada.
Como parte dessas pesquisas, MFC examina todas as DLLs de extensão em uso percorrendo uma cadeia de CDynLinkLibrary objetos.CDynLinkLibrary objetos anexar automaticamente uma cadeia durante sua construção e são criados por cada extensão DLL por sua vez durante a inicialização.Além disso, cada módulo (aplicativo ou DLL regular) tem sua própria cadeia de CDynLinkLibrary objetos.
Para uma extensão DLL para obter com fio em um CDynLinkLibrary cadeia, ele deve criar um CDynLinkLibrary objeto no contexto de cada módulo que usa a extensão DLL.Portanto, se uma extensão DLL for ser usado de DLLs normais, ele deve fornecer uma função de inicialização exportado que cria um CDynLinkLibrary objeto.Cada DLL comum que usa a extensão DLL deve chamar a função de inicialização exportado.
Se uma extensão DLL só vai ser usado em um aplicativo MFC (. exe) e nunca de uma DLL regular, é suficiente para criar o CDynLinkLibrary a DLL de extensão objeto DllMain.Este é o que faz a extensão do Assistente de DLL do MFC código da DLL.Ao carregar uma DLL de extensão implicitamente, DllMain carrega e executa antes do aplicativo nunca inicia.Qualquer CDynLinkLibrary criações são conectadas em uma cadeia padrão que a DLL do MFC reserva para um aplicativo do MFC.
Observe que é ruim ter vários CDynLinkLibrary objetos de uma DLL de extensão em qualquer uma cadeia, especialmente se a extensão DLL serão descarregada dinamicamente da memória.Não chame a função de inicialização mais de uma vez de um módulo qualquer.
Código de Exemplo
Este código de exemplo pressupõe que o normal DLL é implicitamente vinculando a DLL de extensão.Isso é feito vinculando a importar biblioteca (. lib) de extensão DLL ao criar a DLL regular.
As seguintes linhas devem estar na origem da extensão DLL:
// YourExtDLL.cpp:
// standard MFC extension DLL routines
#include "afxdllx.h"
static AFX_EXTENSION_MODULE NEAR extensionDLL = { NULL, NULL };
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// 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 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 InitYourExtDLL função.Isso pode ser feito usando __declspec(dllexport) ou no arquivo. def da DLL da seguinte maneira:
// YourExtDLL.Def:
LIBRARY YOUREXTDLL
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD SINGLE
EXPORTS
InitYourExtDLL
Adicionar uma chamada para o InitInstance membro o CWinApp-derivado objeto em cada DLL normal usando a extensão DLL:
// 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 DLL initializing\n");
// wire any extension DLLs into CDynLinkLibrary chain
InitYourExtDLL();
return TRUE;
}