Exportando e importando usando AFX_EXT_CLASS
As DLLs de extensão de MFC usam a macro AFX_EXT_CLASS para exportar classes; os executáveis que vinculam à DLL de extensão de MFC usam a macro para importar classes. Com a macro AFX_EXT_CLASS, os mesmos arquivos de cabeçalho usados para criar a DLL da extensão de MFC podem ser usados com os executáveis que se vinculam à DLL.
No arquivo de cabeçalho da DLL, adicione a palavra-chave AFX_EXT_CLASS à declaração da classe da seguinte maneira:
class AFX_EXT_CLASS CMyClass : public CDocument
{
// <body of class>
};
Essa macro é definida pelo MFC como __declspec(dllexport)
quando o pré-processador símbolos _AFXDLL
e _AFXEXT
são definidos. Mas a macro é definida como __declspec(dllimport)
quando _AFXDLL
é definida e _AFXEXT
não está definida. Quando definido, o símbolo _AFXDLL
do pré-processador indica que a versão compartilhada do MFC está sendo usada pelo executável de destino (uma DLL ou um aplicativo). Quando ambos _AFXDLL
e _AFXEXT
são definidos, isso indica que o executável de destino é uma DLL de extensão MFC.
Como AFX_EXT_CLASS
é definido como __declspec(dllexport)
ao exportar de uma DLL de extensão MFC, você pode exportar classes inteiras sem colocar os nomes decorados para todos os símbolos dessa classe no arquivo .def.
Embora você possa evitar a criação de um arquivo .def e todos os nomes decorados para a classe com esse método, a criação de um arquivo .def é mais eficiente porque os nomes podem ser exportados por ordinal. Para usar o método de exportação de arquivo .def, coloque o seguinte código no início e no final do arquivo de cabeçalho:
#undef AFX_DATA
#define AFX_DATA AFX_EXT_DATA
// <body of your header file>
#undef AFX_DATA
#define AFX_DATA
Cuidado
Tenha cuidado ao exportar funções embutidas, pois elas podem criar a possibilidade de conflitos de versão. Uma função embutida é expandida no código do aplicativo, portanto, se você reescrever a função posteriormente ela não será atualizada, exceto se o próprio aplicativo for recompilado. Normalmente, as funções de DLL podem ser atualizadas sem recompilar os aplicativos que as utilizam.
Exportando membros individuais em uma classe
Às vezes, talvez você queira exportar membros individuais da sua classe. Por exemplo, se você exportar uma classe derivada de CDialog
, talvez seja necessário exportar apenas o construtor e a chamada DoModal
. Você pode usar AFX_EXT_CLASS
nos membros individuais necessários para exportar.
Por exemplo:
class CExampleDialog : public CDialog
{
public:
AFX_EXT_CLASS CExampleDialog();
AFX_EXT_CLASS int DoModal();
...
// rest of class definition
...
};
Como você não está mais exportando todos os membros da classe, pode ter um problema adicional devido à maneira como as macros MFC funcionam. Várias macros auxiliares do MFC realmente declaram ou definem membros de dados. Portanto, esses membros de dados também devem ser exportados de sua DLL.
Por exemplo, a macro DECLARE_DYNAMIC
é definida da seguinte maneira ao compilar uma DLL de extensão do MFC:
#define DECLARE_DYNAMIC(class_name) \
protected: \
static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
static AFX_DATA CRuntimeClass class##class_name; \
virtual CRuntimeClass* GetRuntimeClass() const; \
A linha que começa com estática AFX_DATA
é declarar um objeto estático dentro de sua classe. Para exportar essa classe corretamente e acessar as informações de tempo de execução de um executável do cliente, você deve exportar esse objeto estático. Como o objeto estático é declarado com o modificador AFX_DATA
, você só precisa definir AFX_DATA
como __declspec(dllexport)
ao criar sua DLL e defini-la como __declspec(dllimport)
ao criar o executável do cliente. Como AFX_EXT_CLASS
já está definido dessa forma, você só precisa redefinir AFX_DATA
para ser o mesmo AFX_EXT_CLASS
que em torno de sua definição de classe.
Por exemplo:
#undef AFX_DATA
#define AFX_DATA AFX_EXT_CLASS
class CExampleView : public CView
{
DECLARE_DYNAMIC()
// ... class definition ...
};
#undef AFX_DATA
#define AFX_DATA
Como o MFC sempre usa o símbolo AFX_DATA
em itens de dados que define dentro de suas macros, essa técnica funcionará para todos esses cenários. Por exemplo, ele funciona para DECLARE_MESSAGE_MAP
.
Observação
Se você estiver exportando toda a classe em vez de membros selecionados da classe, os membros de dados estáticos serão exportados automaticamente.
O que você deseja fazer?
Exportar funções do C++ para usar em executáveis da linguagem C
Exportar funções do C para usar em executáveis da linguagem C ou C++