TN011: Usando o MFC como parte de uma DLL
Esta anotação descreve DLLs regulares, que permitem que você use a biblioteca MFC como parte de uma biblioteca de vínculo dinâmico (DLL) do Windows.Ele pressupõe que você esteja familiarizado com DLLs do Windows e como criá-los.Para obter informações sobre DLLs de extensão do MFC, com o qual você pode criar extensões para a biblioteca MFC, consulte Versão de DLL da MFC.
Interfaces DLL
DLLs normais assumem interfaces entre o aplicativo e a DLL são especificados em c como funções ou classes explicitamente exportados.Interfaces de classe do MFC não podem ser exportados.
Se uma DLL e um aplicativo quiser usar MFC, ambos têm uma opção para usar a versão compartilhada das bibliotecas MFC ou estaticamente vincular a uma cópia das bibliotecas.O aplicativo e DLL podem usam uma das versões da biblioteca MFC padrão.
DLLs normais têm várias vantagens:
O aplicativo que usa a DLL não precisa usar MFC e não precisa ser um aplicativo do Visual C++.
Com regulares DLLs vinculadas estaticamente a MFC, o tamanho da DLL depende somente as rotinas de tempo de execução MFC e c que são usadas e vinculadas.
Com DLLs normais que vincular dinamicamente a MFC, a economia na memória usando a versão compartilhada do MFC pode ser significativa.No entanto, você deve distribuir as compartilhada DLLs, Mfc<version>. dll e Msvvcrt<version>. dll, com sua DLL.
O projeto DLL é independente de como as classes são implementadas.Design DLL Exporta somente para as APIs desejado.Como resultado, se a implementação for alterado, DLLs normais ainda são válidas.
Com regulares DLLs vinculadas estaticamente a MFC, se a DLL e o aplicativo usarem MFC, há problemas com o aplicativo que deseja uma versão diferente do MFC a DLL ou vice-versa.Como a biblioteca MFC estiver vinculada estaticamente em cada DLL ou EXE, não há nenhuma pergunta sobre qual versão você tem.
Limitações de API
Algumas funcionalidades do MFC não se aplica à versão de DLL devido a limitações técnicas ou porque esses serviços são geralmente fornecidos pelo aplicativo.Com a versão atual do MFC, é a única função que não é aplicável CWinApp::SetDialogBkColor.
Criando sua DLL
Durante a compilação regulares DLLs vinculadas estaticamente a MFC, os símbolos _USRDLL e _WINDLL deve ser definido.O código da DLL também deve ser compilado com as seguintes opções do compilador:
/D_WINDLLsignifica que a compilação é para uma DLL
/D_USRDLLEspecifica a que criação de uma DLL regular
Você também deve definir esses símbolos e usar essas opções do compilador quando você compila DLLs normais que vincular dinamicamente a MFC.Além disso, o símbolo _AFXDLL deve ser definido e seu código DLL deve ser compilado com:
- /D_AFXDLLEspecifica que você esteja criando uma DLL regular que vincula dinamicamente a MFC
As interfaces (APIs) entre o aplicativo e a DLL devem ser exportadas explicitamente.É recomendável definir suas interfaces de ser baixa largura de banda e usar interfaces somente c se possível.Interfaces c diretas são mais fáceis de manter de classes C++ mais complexa.
Coloque suas APIs em um cabeçalho separado que pode ser incluído por arquivos c e C++.Consulte o cabeçalho ScreenCap.h exemplo MFC avançado conceitos DLLScreenCap para obter um exemplo.Para exportar suas funções, inseri-los a EXPORTS seção do seu arquivo de definição de módulo (.DEF) ou incluir __declspec(dllexport) em suas definições de função.Use __declspec(dllimport) para importar essas funções para o executável do cliente.
Você deve adicionar o AFX_MANAGE_STATE macro no início de todas as funções exportadas em DLLs normais que vincular dinamicamente a MFC.Essa macro define o estado atual do módulo para o outro para a DLL.Para usar essa macro, adicione a seguinte linha de código para o início de funções exportadas da DLL:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
WinMain - > DllMain
A biblioteca MFC define Win32 padrão DllMain ponto de entrada que inicializa o CWinApp derivado do objeto em um aplicativo do MFC típico.Coloque todos os DLL específica na InitInstance método como em um aplicativo do MFC típico.
Observe que o CWinApp::Run mecanismo não se aplica a uma DLL, porque o aplicativo que detém a bomba de mensagem principal.Se sua DLL exibe caixas de diálogo sem janela restrita ou tiver uma janela de quadro principal de seu próprio, bomba de mensagem principal do aplicativo deve chamar uma rotina de exportado a DLL que chama CWinApp::PreTranslateMessage.
Consulte o exemplo de DLLScreenCap para uso desta função.
O DllMain função MFC fornece irá chamar o CWinApp::ExitInstance método de sua classe derivada de CWinApp antes que a DLL é descarregada.
Vinculando sua DLL
Com regulares DLLs vinculadas estaticamente a MFC, você deve vincular sua DLL com Nafxcwd. lib ou Nafxcw.lib e com a versão dos tempos de execução c chamados Libcmt.lib.Essas bibliotecas são pré instaladas e podem ser instaladas, especificando-os ao executar a instalação do Visual C++.
Código de Exemplo
Consulte o exemplo MFC avançado conceitos programa DLLScreenCap para obter um exemplo completo.Várias coisas interessantes para observar neste exemplo são:
Os sinalizadores de compilador da DLL e aqueles do aplicativo são diferentes.
Linhas de vínculo e.Arquivos de definição para a DLL e aqueles do aplicativo são diferentes.
O aplicativo que usa a DLL não tem em C++.
A interface entre o aplicativo e a DLL é uma API que é utilizável por c ou C++ e é exportada com DLLScreenCap.def.
O exemplo a seguir ilustra uma API que é definida em uma DLL regular que vincula estaticamente ao MFC.Neste exemplo, a declaração é colocada entre um extern "C" { } bloco para os usuários do C++.Isso tem várias vantagens.Primeiro, faz a APIs de DLL utilizável por aplicativos cliente C++ não.Segundo, ele reduz a sobrecarga DLL porque C++ desconfiguração do nome não será aplicada para o nome exportado.Finalmente, ele torna mais fácil adicionar explicitamente a um.Arquivo DEF (para exportação por ordinal) sem precisar se preocupar sobre a desconfiguração do nome.
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct TracerData
{
BOOL bEnabled;
UINT flags;
};
BOOL PromptTraceFlags(TracerData FAR* lpData);
#ifdef __cplusplus
}
#endif
As estruturas usadas pela API não são derivadas de classes do MFC e definidas no cabeçalho da API.Isso reduz a complexidade da interface entre o aplicativo e a DLL e torna a DLL utilizáveis por programas em C.