Importações mútuas
Exportar ou importar outro arquivo executável apresenta complicações quando as importações são mútua (ou circular).Por exemplo, duas DLLs importar símbolos de cada Outros, semelhante às funções de recursiva mutuamente.
O problema com a importação mutuamente arquivos executável (geralmente DLLs) é que nenhuma delas pode ser criada sem construir Outros primeiro.Cada processo de construção requer, sistema autônomo entrada, uma biblioteca de importação produzida pelo processo de compilação.
A solução é usar o utilitário LIB com a opção /DEF, que produz uma biblioteca de importação sem a criação do arquivo executável.Usando esse utilitário, você pode compilação todas as bibliotecas de importação for necessário, não importa quantos DLLs envolvidas ou complicados como as dependências são.
A solução geral para a manipulação de importações mútuas é:
Levar cada DLL por sua vez.(Qualquer ordem é viável, embora alguns pedidos sejam mais ideais). Se todos as bibliotecas de importação necessário existem e estão atual, executar o LINK para compilação o arquivo executável (DLL).Isso produz uma biblioteca de importação.Caso contrário, execute o LIB para produzir uma biblioteca de importação.
Executando LIB com a opção /DEF produz um arquivo com uma extensão .EXP adicional.O arquivo .EXP deve ser usado posteriormente para compilação o arquivo executável.
Depois de usar o LINK ou LIB para compilação todas as bibliotecas de importação, volte e executar o LINK para compilação todos os arquivos executável que não foram criados na etapa anterior.Observe que o arquivo .exp correspondente deve ser especificado linha de vínculo.
Se você tivesse executar o utilitário LIB anterior para produzir uma biblioteca de importação para DLL1, LIB seria produzida o arquivo DLL1.exp sistema autônomo bem.Você deve usar DLL1.exp sistema autônomo entrada para o LINK ao criar DLL1.dlll.
A ilustração a seguir mostra uma solução para duas DLLs de importação mutuamente, DLL1 e DLL2.Etapa 1 é executar LIB, com a opção /DEF definida, em DLL1.Etapa 1 produz DLL1.lib, uma biblioteca de importação e DLL1.exp.Na etapa 2, a biblioteca de importação é usada para compilação DLL2, que por sua vez produz uma biblioteca de importação símbolos do DLL2.Etapa 3 cria DLL1, usando DLL1.exp e DLL2.lib sistema autônomo entrada.Observe que um arquivo .exp para DLL2 não é necessário porque LIB não foi usado para criar biblioteca de importação do DLL2.
Vinculando duas DLLs com Imports mútuas
Limitações do _AFXEXT
Você pode usar o _AFXEXT símbolo de pré-processador para sua extensão DLLs, desde que você não tem várias camadas de DLLs de extensão. Se você tiver DLLs de extensão que telefonar ou derivar de classes em sua própria extensão DLLs, que, em seguida, derivam das classes MFC, você deve usar seu próprio símbolo de pré-processador para evitar ambigüidade.
O problema é que, em Win32, você deve declarar explicitamente todos sistema autônomo dados sistema autônomo __declspec(dllexport) se estiver a ser exportado de uma DLL e __declspec(DllImport) se estiver a ser importado de uma DLL.Quando você define _AFXEXT, os cabeçalhos MFC, certifique-se AFX_EXT_CLASS está definido corretamente.
Quando você tiver várias camadas, um símbolo, sistema autônomo AFX_EXT_CLASS não é suficiente, porque uma DLL de extensão pode ser exportando novas classes, assim sistema autônomo a importação de outras classes de Outros extensão DLL.Para solucionar esse problema, use um símbolo de pré-processador especial que indica que você esteja criando a DLL em vez de usar a DLL.Por exemplo, imagine B.dll, A.dll e DLLs de extensão dois.Cada um deles exportar algumas classes A.h e B.h, respectivamente.B.dll usa as classes de A.dll.Os arquivos de cabeçalho devem ter esta aparência:
/* A.H */
#ifdef A_IMPL
#define CLASS_DECL_A __declspec(dllexport)
#else
#define CLASS_DECL_A __declspec(dllimport)
#endif
class CLASS_DECL_A CExampleA : public CObject
{ ... class definition ... };
// B.H
#ifdef B_IMPL
#define CLASS_DECL_B __declspec(dllexport)
#else
#define CLASS_DECL_B __declspec(dllimport)
#endif
class CLASS_DECL_B CExampleB : public CExampleA
{ ... class definition ... };
...
Quando A.dll é construído, ele é criado com /D A_IMPL e quando B.dll é construído, ele é incorporado com /D B_IMPL. Usando separado símbolos para cada DLL, CExampleB é exportada e CExampleA é importado quando estiver criando B.dll. CExampleA for exportado quando estiver criando A.dll e importado quando usado por B.dll (ou Outros cliente).
Esse tipo de disposição em camadas não pode ser concluído ao usar o interno AFX_EXT_CLASS and _AFXEXT símbolos de pré-processador. A técnica descrita acima resolve esse problema de maneira não diferentemente que o mecanismo de MFC se usa ao criar suas tecnologias ativo, banco de dados e DLLs de extensão de rede.
Não exportar a classe inteira
Quando você não estiver exportando uma classe inteira, você precisa garantir que os itens de dados necessários criados pelas macros MFC são exportados corretamente.Isso pode ser concluído por redefinindo AFX_DATA a macro da classe específica. Isso deve ser concluído a qualquer momento que você está exportando não toda a turma.
Por exemplo:
/* A.H */
#ifdef A_IMPL
#define CLASS_DECL_A _declspec(dllexport)
#else
#define CLASS_DECL_A _declspec(dllimport)
#endif
#undef AFX_DATA
#define AFX_DATA CLASS_DECL_A
class CExampleA : public CObject
{
DECLARE_DYNAMIC()
CLASS_DECL_A int SomeFunction();
//... class definition ...
};
#undef AFX_DATA
#define AFX_DATA