Compartilhar via


Usando banco de dados, OLE e DLLs de extensão de soquetes em DLLs regulares

Ao usar uma extensão DLL de uma DLL regular, se a extensão DLL não está conectado para o CDynLinkLibrary objeto cadeia da DLL regular, você pode executar em um ou mais de um conjunto de problemas relacionados.sistema autônomo sistema autônomo versões de depurar do banco de dados MFC, OLE e soquetes dão suporte a DLLs são implementadas sistema autônomo DLLs de extensão, você pode receber apresenta problemas semelhantes, se você estiver usando esses MFC, 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 do tipo de classe definidos na extensão DLL, a mensagem "Aviso: Não é possível carregar CYourClass do arquivar.Classe não definida."aparece na janela de depurar TRACE e o objeto não for serializar.

  • Pode ser lançada uma exceção que indica a classe incorreta.

  • Recursos armazenados na DLL de extensão Falha ao carregar porque AfxFindResourceHandle Retorna NULO ou um identificador de recurso incorreto.

  • DllGetClassObject, DllCanUnloadNowe o UpdateRegistry, Revoke, RevokeAll, e RegisterAll funções de membro de COleObjectFactory Falha ao localizar uma fábrica de classes definida na DLL de extensão.

  • AfxDoForAllClasses não funciona para qualquer classe na DLL de extensão.

  • Padrão de banco de dados MFC, soquetes ou recursos OLE Falha ao carregar.Por exemplo, AfxLoadString(AFX_IDP_SQL_CONNECT_FAIL) Retorna uma seqüência de caracteres vazia, mesmo quando a DLL regular é corretamente usando as classes de banco de dados MFC.

A solução para esses problemas é para criar e exportar uma função de inicialização na extensão DLL que cria um CDynLinkLibrary objeto.telefonar Essa função de inicialização exatamente uma vez por cada DLL regular que usa a DLL de extensão.

MFC OLE, banco de dados MFC (ou DAO) ou o suporte de Sockets do MFC

Se você estiver usando qualquer MFC OLE, banco de dados MFC (ou DAO) ou soquetes MFC suporte na sua DLL regular, respectivamente, o MFCOxxD.dll DLLs de extensão de depurar do MFC, MFCDxxD.dll e MFCNxxD.dll (onde xx é o número de versão) são vinculados automaticamente.Você deve telefonar uma função de inicialização predefinidas para cada uma dessas DLLs que você está usando.

Para obter suporte de banco de dados, adicione uma telefonar para AfxDbInitModule para sua DLL regular CWinApp::InitInstance função. Certifique-se de que esta telefonar ocorre antes de qualquer telefonar de classe base ou código que acessa o MFCDxxD.dll nenhum adicionado.Esta função não usa nenhum parâmetro e retorno nula.

Para obter suporte OLE, adicione uma telefonar para AfxOleInitModule para sua DLL regular CWinApp::InitInstance. Observe que o CWinAppEx COleControlModule chamadas de função AfxOleInitModule já, portanto, se você estiver criando um controle OLE e usar COleControlModule, você não deve adicionar esta telefonar para AfxOleInitModule.

Para suporte de soquetes de segurança, adicione uma telefonar para AfxNetInitModule para sua DLL regular CWinApp::InitInstance.

Observe que a versão compilações do MFC DLLs e aplicativos não usam DLLs separadas para o banco de dados, soquetes, ou oferecer suporte a OLE.No entanto, é seguro chamar essas funções de inicialização no modo de versão.

Objetos CDynLinkLibrary

Durante cada operação mencionadas no início deste tópico, MFC precisa procurar um objeto ou um valor desejado.Por exemplo, durante a desserialização, MFC precisa pesquisar em todas as classes de time de execução disponível atualmente para corresponder aos objetos no arquivar com classe de time de execução adequada.

sistema autônomo parte dessas pesquisas, MFC examina através de todas sistema autônomo DLLs de extensão em uso percorrendo uma cadeia de CDynLinkLibrary objetos.CDynLinkLibrary objetos conectar automaticamente a uma cadeia durante sua construção e são criados por cada DLL de extensão por sua vez durante a inicialização.Além disso, cada módulo (aplicativo ou DLL regular) tem seu próprio 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 DLL de extensão.Portanto, se uma extensão DLL a ser usado em DLLs normais, ele deverá fornecer uma função de inicialização exportada que cria um CDynLinkLibrary objeto.Cada DLL regular que usa a extensão DLL deve telefonar a função de inicialização exportada.

Se uma extensão DLL somente for ser usado de um aplicativo MFC (.exe) e nunca de uma DLL regular, em seguida, é suficiente para criar o CDynLinkLibrary objeto DllMain. Este é o que faz a extensão do MFC DLL assistente código da DLL.Ao carregar uma DLL de extensão implicitamente, DllMain carrega e executa antes do aplicativo nunca inicia. Any CDynLinkLibraryCriações de são conectadas em uma cadeia padrão que a DLL da MFC reserva para um aplicativo MFC.

Observe que é uma boa idéia ter vários CDynLinkLibrary objetos de uma DLL de extensão em qualquer uma cadeia, especialmente se a DLL de extensão será dinamicamente descarregada da memória.Não chame a função de inicialização mais de uma vez de qualquer um módulo.

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 biblioteca de importação (.lib) da extensão DLL ao criar a DLL normal.

As seguintes linhas devem estar no código-fonte da DLL de extensão:

// 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 que você exportou a InitYourExtDLL função.Isso pode ser concluído usando __declspec(dllexport) ou no arquivo de .def da sua DLL da seguinte maneira:

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

Adicione uma telefonar para o InitInstance membro de CWinApp-derivados do objeto em cada DLL regular usando a DLL de extensão:

// 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;
}

O que você deseja fazer?

O que você deseja saber mais sobre?

Consulte também

Conceitos

DLLs de extensão