Compartilhar via


Importações mútuas

Exportando ou importando 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 si, semelhante às funções de recursiva mutuamente.

O problema com a importação mutuamente arquivos executáveis (geralmente DLLs) é que nenhuma delas pode ser criada sem construir outro primeiro.Como entrada, cada processo de compilação requer 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 criar o arquivo executável.Usando esse utilitário, você pode criar todas as bibliotecas de importação você precisa, não importa quantas DLLs envolvidas ou são as dependências como complicado.

A solução geral para manipulação importações mútuas é:

  1. Leve cada DLL por sua vez.(Qualquer ordem é viável, embora alguns pedidos são mais ideais). Se todas as bibliotecas de importação necessários existem e estão atuais, execute o LINK para criar o arquivo executável (DLL).Isso produz uma biblioteca de importação.Caso contrário, execute LIB para produzir uma biblioteca de importação.

    Executando LIB com a opção /DEF produz um arquivo adicional com um.Extensão EXP.O.EXP arquivo deve ser usado posteriormente para criar o arquivo executável.

  2. Após usar o LINK ou LIB para criar todas as bibliotecas de importação, volte e execute o LINK para criar os arquivos executáveis que não foram criados na etapa anterior.Observe que o arquivo correspondente de .exp deve ser especificado na linha de vínculo.

    Se você tivesse executado o utilitário LIB anteriormente para produzir uma biblioteca de importação para DLL1, LIB vai ter também o arquivo DLL1.exp.Você deve usar DLL1.exp como 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 o conjunto de opção /DEF, 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 construir DLL2, que por sua vez produz uma biblioteca de importação para símbolos do DLL2.Etapa 3 cria DLL1, usando DLL1.exp e DLL2.lib como entrada.Observe que um arquivo de .exp para DLL2 não é necessário porque LIB não foi usado para criar a biblioteca de importação do DLL2.

Vinculando duas DLLs com importações mútuas

Importações mútuas vinculadas 2DLLs

Limitações do _AFXEXT

Você pode usar o _AFXEXT símbolo do pré-processador para sua extensão DLLs desde que você não tem várias camadas de DLLs de extensão.Se você tiver extensão DLLs que chamar ou derivam de classes em sua própria extensão DLLs, que então derivar classes MFC, você deve usar seu próprio símbolo do pré-processador para evitar ambigüidade.

O problema é que no Win32, você deve explicitamente declarar todos os dados como __declspec(dllexport) se estiver a ser exportado de uma DLL, e __declspec(dllimport) se estiver a ser importado de uma DLL.Quando você definir _AFXEXT, os cabeçalhos MFC, certifique-se AFX_EXT_CLASS está definido corretamente.

Quando você tiver várias camadas, um símbolo, como AFX_EXT_CLASS não é suficiente, porque uma DLL de extensão pode ser exportando novas classes, bem como a importação de outras classes de outra extensão DLL.Para resolver esse problema, use um símbolo de pré-processamento especial que indica que você esteja criando DLL versus usando a DLL.Por exemplo, imagine DLLs de extensão de dois, a. dll e b. dll.Cada exportar algumas classes A.h e B.h, respectivamente.B. dll usa as classes de DLL.Os arquivos de cabeçalho poderiam 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 é criado, ele é criado com /D A_IMPL e quando b. dll é criado, ele é criado com /D B_IMPL.Usando símbolos separados para cada DLL CExampleB é exportado e CExampleA é importado ao criar b. dll.CExampleAé exportada ao criar a dll e importados quando usado por b. dll (ou outro cliente).

Esse tipo de camadas não pode ser feito quando uso interno AFX_EXT_CLASS e _AFXEXT símbolos de pré-processamento.A técnica descrita acima resolve esse problema de maneira não ao contrário das que mecanismo MFC próprio usa ao criar seu ativas tecnologias, banco de dados e DLLs de extensão de rede.

Não exportando a classe inteira

Quando você não estiver exportando uma classe inteira, você precisa garantir que os itens de dados necessários criados por macros MFC são exportados corretamente.Isso pode ser feito, redefinindo AFX_DATA a macro da sua classe específica.Isso deve ser feito a qualquer momento que você não estiver exportando uma classe inteira.

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

fdy23fx6.collapse_all(pt-br,VS.110).gifO que você deseja fazer?

fdy23fx6.collapse_all(pt-br,VS.110).gifO que você deseja saber mais sobre?

Consulte também

Conceitos

Importação e exportação