Поделиться через


Экспорт строковых классов с помощью CStringT

В прошлом разработчики MFC производились от CString специализации собственных строковых классов. В Microsoft Visual C++.NET (MFC 8.0) класс CString был заменен классом шаблона CStringT. Это обеспечило несколько преимуществ:

  • Это позволило использовать класс MFC CString в проектах ATL без связывания в более крупной статической библиотеке или библиотеке DLL MFC.

  • С помощью нового CStringT класса шаблона можно настроить CString поведение с помощью параметров шаблона, которые указывают признаки символов, аналогичные шаблонам в стандартной библиотеке C++.

  • При экспорте собственного класса строк из библиотеки DLL с помощью CStringTкомпилятор также автоматически экспортирует базовый CString класс. Так как CString это класс шаблона, он может быть создан компилятором при использовании, если компилятор не знает, что CString импортируется из библиотеки DLL. Если вы перенесли проекты из Visual C++ 6.0 в Visual C++.NET, возможно, вы видели ошибки символов компоновщика для умножения, определяемого из-за CString столкновения CString импортированного из библиотеки DLL и локально созданной версии. Ниже описано правильное выполнение этого действия.

Следующий сценарий приведет к возникновению ошибок символов компоновщика для умножения определенных классов. Предположим, что вы экспортируете производный CStringкласс (CMyString) из библиотеки DLL расширения MFC:

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

В коде потребителя используется смесь CString и CMyString. "MyString.h" не включается в предварительно скомпилированные заголовки, а некоторые виды использования CString не отображаются CMyString .

Предположим, что вы используете CString и CMyString классы в отдельных исходных файлах, Source1.cpp и Source2.cpp. В Source1.cpp используется CMyString и #include MyString.h. В Source2.cpp используется CString, но не #include MyString.h. В этом случае компоновщик будет жаловаться на CStringT умножение определения. Это вызвано импортом CString из библиотеки DLL, которая экспортирует CMyStringи создает экземпляр локально компилятором с помощью CStringT шаблона.

Чтобы устранить эту проблему, выполните следующие действия.

Экспорт CStringA и CStringW (и необходимые базовые классы) из MFC90.DLL. Проекты, включающие MFC, всегда будут использовать экспортированные CStringA библиотеки DLL MFC, CStringWкак и в предыдущих реализациях MFC.

Затем создайте экспортируемый производный класс с помощью CStringT шаблона, как CStringT_Exported показано ниже, например:

#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
};

В AfxStr.h замените предыдущие CStringCStringAи CStringW typedefs следующим образом:

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

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

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

Существует несколько предостережения:

  • Не следует экспортировать себя, так как это приведет к экспорту CStringT специализированного CStringT класса только для ATL.

  • Использование экспортируемого производного класса из CStringT минимизации необходимости повторной реализации CStringT функциональных возможностей. Дополнительный код ограничен переадресацией конструкторов в базовый CStringT класс.

  • CString, CStringAи CStringW должны быть помечены __declspec(dllexport/dllimport) только при создании с помощью общей библиотеки DLL MFC. При связывании со статической библиотекой MFC не следует пометить эти классы как экспортированные; в противном случае внутреннее использование , CStringAа также CStringW внутри пользовательских CStringбиблиотек DLL будет помечаться CString как экспортированные.

Класс CStringT

См. также

Использование CStringT
Использование CString