DLLs de extensão
Uma extensão do MFC a DLL é uma DLL que normalmente implementa reutilizáveis classes derivadas de classes de biblioteca Microsoft Foundation Class existentes.
Uma DLL de extensão do MFC tem os recursos e os requisitos a seguir:
O executável do cliente deve ser um aplicativo MFC, compilado com _AFXDLL definido.
Uma extensão DLL também pode ser usada uma DLL de regular está dinamicamente vinculada ao MFC.
DLLs de extensão devem ser compiladas com _AFXEXT definido. Isso força _AFXDLL também ser definido e garante que as declarações apropriadas é retirada do que os arquivos de cabeçalho do MFC. Ele também garante que AFX_EXT_CLASS é definido como __declspec(dllexport) ao criar a DLL, que é necessário se você estiver usando essa macro para declarar as classes na sua extensão DLL.
DLLs de extensão não devem instanciar uma classe derivada de CWinApp, mas deve depender do aplicativo cliente (ou DLL) para fornecer esse objeto.
DLLs de extensão devem, no entanto, fornecer uma DllMain de função e faça qualquer inicialização necessária lá.
DLLs de extensão são criadas usando a versão da biblioteca de vínculo dinâmico do MFC (também conhecido como a versão compartilhada do MFC). Somente executáveis MFC (aplicativos ou DLLs normais) que são criados com a versão compartilhada do MFC podem usar uma DLL de extensão. O aplicativo do cliente e a DLL de extensão devem usar a mesma versão do MFCx0.dll. Com uma DLL de extensão, você pode derivar novas classes personalizadas a MFC e, em seguida, oferecer essa versão estendida do MFC para aplicativos que chamam a sua DLL.
DLLs de extensão também podem ser usadas para passar objetos derivados de MFC entre o aplicativo e a DLL. As funções de membro associadas com o objeto passado existem no módulo onde o objeto foi criado. Porque essas funções são exportadas corretamente quando usando a versão DLL compartilhada do MFC, você pode passar livremente MFC ou ponteiros para objetos derivados de MFC entre um aplicativo e a extensão de DLLs que ele carrega.
Uma DLL de extensão do MFC usa uma versão compartilhada MFC da mesma forma que um aplicativo usa a versão DLL compartilhada do MFC, com algumas considerações adicionais:
Ele não tem um CWinApp-derivado do objeto. Ele deve funcionar com o CWinApp-derivado de objeto do aplicativo cliente. Isso significa que o aplicativo cliente que detém a bomba de mensagem principal, o loop ocioso e assim por diante.
Ele chama AfxInitExtensionModule no seu DllMain função. O valor de retorno dessa função deve ser verificado. Se um valor zero é retornado de AfxInitExtensionModule, retornar 0 do seu DllMain função.
Ele cria um CDynLinkLibrary objeto durante a inicialização se a extensão DLL quer exportar CRuntimeClass objetos ou recursos para o aplicativo.
Antes da versão 4.0 do MFC, esse tipo de DLL foi chamado um AFXDLL. AFXDLL se refere a _AFXDLL símbolo do pré-processador que é definido ao criar a DLL.
As bibliotecas de importação para a versão compartilhada do MFC são nomeadas de acordo com a convenção descrita em as convenções de nomenclatura para DLLs de MFC. Visual C++ fornece versões pré-construídos as DLLs do MFC, além de um número de não - MFC DLLs que você pode usar e distribuir com seus aplicativos. Esses são documentados em Redist. txt, que é instalado na pasta de Visual Studio de Programas\Microsoft do programa.
Se você estiver exportando usando um arquivo. def, coloque o seguinte código no início e fim do seu arquivo de cabeçalho:
#undef AFX_DATA
#define AFX_DATA AFX_EXT_DATA
// <body of your header file>
#undef AFX_DATA
#define AFX_DATA
Estas quatro linhas garantem que seu código seja compilado corretamente para uma DLL de extensão. Deixando estas quatro linhas pode causar sua DLL compilar ou vincular incorretamente.
Se você precisar passar um MFC ou ponteiro de objeto derivado de MFC para ou de uma DLL da MFC, a DLL deve ser uma extensão DLL. As funções de membro associadas com o objeto passado existem no módulo onde o objeto foi criado. Porque essas funções são exportadas corretamente quando usando a versão DLL compartilhada do MFC, você pode passar livremente MFC ou ponteiros para objetos derivados de MFC entre um aplicativo e a extensão de DLLs que ele carrega.
Devido a C++ nome desconfiguração e exportação problemas, a lista de exportação de uma extensão DLL pode ser diferente entre as versões de depuração e varejo da mesma DLL e DLLs para diferentes plataformas. O MFCx0.dll de varejo tem cerca de 2.000 exportados pontos de entrada; a MFCx0D.dll de depuração tem aproximadamente 3.000 pontos de entrada exportada.
Gerenciamento de memória
MFCx0.dll e todas as DLLs de extensão carregados na utilização de espaço de endereço de um aplicativo cliente o alocador de memória mesmo, carregamento de recursos e outros estados MFC globais como se estivessem no mesmo aplicativo. Isso é significativo porque as bibliotecas de DLL não - MFC e as DLLs regulares fazer o oposto exato e tem a cada alocação de DLL fora do seu próprio pool de memória.
Se uma DLL de extensão aloca a memória, o que a memória pode combinar livremente com qualquer outro objeto alocado pelo aplicativo. Além disso, se um aplicativo que se vincula ao MFC dinamicamente falhar, a proteção do sistema operacional mantém a integridade de qualquer outro aplicativo do MFC a DLL de compartilhamento.
Da mesma forma outros estados MFC globais, como o atual arquivo executável para carregar recursos, também são compartilhados entre o aplicativo cliente e todas as DLLs de extensão do MFC, bem como MFCx0.dll em si.
Compartilhar recursos e Classes
Exportação de recursos é feito por meio de uma lista de recursos. Cada aplicativo contém uma lista vinculada separada de CDynLinkLibrary objetos. Ao procurar um recurso, a maioria das implementações padrão de MFC que carregar recursos analisar primeira o módulo de recurso atual (AfxGetResourceHandle) e se o recurso não for encontrado percorrer a lista de CDynLinkLibrary objetos tentando carregar o recurso solicitado.
Percorrer a lista tem desvantagens, que é um pouco mais lenta e requer o gerenciamento de intervalos de ID de recurso. Ele tem a vantagem de que um aplicativo cliente que vincula a várias DLLs de extensão pode usar qualquer recurso fornecido pelo DLL sem ter que especificar o identificador de instância DLL. AfxFindResourceHandleuma API é usada para percorrer a lista de recursos para procurar uma correspondência de determinado. Ele leva o nome e um tipo de recurso e retorna o identificador de recurso onde foi encontrado primeiro (ou nula).
Se não desejar para orientá-lo da lista e carregar somente os recursos de um local específico, use as funções AfxGetResourceHandle e AfxSetResourceHandle para salvar a alça antiga e definir a nova alça. Certifique-se de restaurar o identificador de recurso antigo antes de retornar para o aplicativo cliente. Para obter um exemplo do uso dessa abordagem para carregar explicitamente um menu, consulte. cpp do Testdll2 em uma amostra MFC DLLHUSK.
Criação dinâmica de objetos do MFC recebe um nome MFC é semelhante. O mecanismo de desserialização do objeto MFC precisa ter todos os CRuntimeClass objetos registrados para que ele pode reconstruir ao criar dinamicamente objetos em C++ do tipo necessário com base no que foi armazenado anteriormente.
No caso do exemplo MFC DLLHUSK, a lista é parecido com:
head -> DLLHUSK.EXE - or - DLLHUSK.EXE
| |
TESTDLL2.DLL TESTDLL2.DLL
| |
TESTDLL1.DLL TESTDLL1.DLL
| |
MFCOxxD.DLL |
| |
MFCDxxD.DLL |
| |
MFCxxD.DLL MFCxx.DLL
onde xx é o número de versão; Por exemplo, 42 representa a versão 4.2.
O MFCxx.dll é geralmente a última na lista de classes e recursos. MFCxx.dll inclui todos os recursos padrão do MFC, incluindo cadeias de caracteres de prompts para todas as IDs de comando padrão. Permite que colocá-lo no final da lista de DLLs e o próprio aplicativo cliente não tem sua própria cópia dos recursos padrão do MFC, mas contam com recursos compartilhados na MFCxx.dll em vez disso.
Mesclando os recursos e os nomes de classe de todas as DLLs espaço para nome do aplicativo cliente tem a desvantagem de exigir que você tenha cuidado com os quais IDs ou nomes que você escolher.
O DLLHUSK exemplo gerencia o espaço de nome do recurso compartilhado usando vários arquivos de cabeçalho.
Se precisar de sua DLL de extensão do MFC manter dados extras para cada aplicativo, você pode derivar uma nova classe de CDynLinkLibrary e criá-lo em DllMain. Quando executado, a DLL pode verificar a lista atual do aplicativo de CDynLinkLibrary objetos para localizar o item para aquela determinada extensão DLL.