Compartilhar via


Exportar classes de cadeia de caracteres usando CStringT

Observação

A biblioteca do Microsoft Foundation Classes (MFC) e a Biblioteca de Modelos Ativos (ATL) continuam com suporte. No entanto, não estamos mais adicionando recursos ou atualizando a documentação.

No passado, os desenvolvedores do MFC fizeram derivação de CString para especializar suas próprias classes de cadeia de caracteres. No .NET (MFC 8.0) do Microsoft Visual C++, a classe CString foi substituída por uma classe de modelo chamada CStringT. Isso forneceu vários benefícios:

  • Permitiu que a classe CString do MFC fosse usada em projetos da ATL sem vinculação na biblioteca estática no MFC maior ou na DLL.

  • Com a nova classe de modelo CStringT, você pode personalizar o comportamento CString usando parâmetros de modelo que especificam características de caractere, semelhantes aos modelos na Biblioteca Padrão C++.

  • Quando você exporta sua própria classe de cadeia de caracteres de uma DLL usando CStringT, o compilador também exporta automaticamente a classe base CString. Como CString é uma classe de modelo, ela pode ser instanciada pelo compilador quando usada, a menos que o compilador esteja ciente de que CString é importado de uma DLL. Se você migrou projetos do Visual C++ 6.0 para o Visual C++ .NET, talvez tenha visto erros de símbolo do vinculador para um CString com multiplicação definida devido à colisão do CString importado de uma DLL e da versão localmente instanciada. A maneira adequada de fazer isso é descrita abaixo.

O cenário a seguir fará com que o vinculador produza erros de símbolo para multiplicar classes definidas. Suponha que você esteja exportando uma classe derivada de CString (CMyString) de uma DLL de extensão MFC:

// MyString.h
class AFX_EXT_CLASS CMyString : public CString
{
   // Your implementation code
};

O código do consumidor usa uma mistura de CString e CMyString. "MyString.h" não está incluído no cabeçalho pré-compilado e alguns usos de CString não têm CMyString visível.

Suponha que você use as classes CString e CMyString em arquivos de origem separados, Source1.cpp e Source2.cpp. Em Source1.cpp, você usa CMyString e #include MyString.h. Em Source2.cpp, você usa CString, mas não usa #include MyString.h. Nesse caso, o vinculador reclamará de CStringT ter sido definido por multiplicação. Isso é causado por CString ser importado da DLL que exporta CMyString e instanciado localmente pelo compilador por meio do modelo CStringT.

Para resolver esse problema, execute uma das seguintes ações:

Exporte CStringA e CStringW (e as classes base necessárias) de MFC90.DLL. Os projetos que incluem o MFC sempre usarão a DLL do MFC exportada CStringA e CStringW, como nas implementações anteriores do MFC.

Em seguida, crie uma classe derivada exportável usando o CStringT modelo, como CStringT_Exported está abaixo, por exemplo:

#ifdef _AFXDLL
   #define AFX_EXT_CSTRING AFX_EXT_CLASS
#else
   #define AFX_EXT_CSTRING
#endif

template< typename BaseType, class StringTraits >
class AFX_EXT_CSTRING CStringT_Exported 
   : public CStringT< BaseType, StringTraits >
{
   // Reimplement all CStringT<> constructors and
   // forward to the base class implementation
};

No AfxStr.h, substitua os typedefs CString, CStringA e CStringW anteriores da seguinte maneira:

typedef CStringT_Exported< wchar_t, 
      StrTraitMFC< wchar_t > > CStringW;

typedef CStringT_Exported< char,
      StrTraitMFC< char > > CStringA;

typedef CStringT_Exported< TCHAR,
      StrTraitMFC< TCHAR > > CString;

Existem várias advertências:

  • Você não deve exportar apenas CStringT porque isso fará com que projetos somente ATL exportem uma classe CStringT especializada.

  • O uso de uma classe derivada exportável de CStringT minimiza a necessidade de implementar novamente a funcionalidade CStringT. O código adicional é limitado ao encaminhamento de construtores para a classe base CStringT.

  • CString, CStringA e CStringW só devem ser marcados como __declspec(dllexport/dllimport) quando você estiver criando com uma DLL compartilhada do MFC. Se estiver vinculando com uma biblioteca estática do MFC, você não deverá marcar essas classes como exportadas. Caso contrário, o uso interno de CString, CStringA e CStringW nas DLLs do usuário também marcará CString como exportado.

Classe CStringT

Confira também

Usando CStringT
Usando CString