DLL-библиотека расширения Singleton MFC - PullRequest
1 голос
/ 07 января 2010

Я объявляю синглтон в DLL-библиотеке расширения MFC, например:

//header file: SingleTon.h
class AFX_EXT_CLASS CMySingleton
{
public:
  static CMySingleton* Instance()
  {
    if(!singleton)
        singleton = new CMySingleton();
    return singleton;
  }

  int a;

// Other non-static member functions
private:
  CMySingleton() {};                                 // Private constructor
  CMySingleton(const CMySingleton&);                 // Prevent copy-construction
  CMySingleton& operator=(const CMySingleton&);      // Prevent assignment
  virtual ~CMySingleton() {};

  static CMySingleton* singleton;
};

And in a cpp file I code the following line:

CMySingleton* CMySingleton::singleton = NULL;

Код 2:

CMySingleton *a;

a = CMySingleton::Instance();

Проблема в том, что когда я кодирую «код 2» в обычном Dll, все работает нормально, но когда я кодирую «код 2» в другой DLL-библиотеке расширения MFC, выдает ошибку:

unresolved external symbol "private: static class CMySingleton* CMySingleton::singleton" (?singleton@CMySingleton@@0PAV1@A)

Я правильно проверяю все зависимости через Project Dependencies.

Есть идеи?

1 Ответ

1 голос
/ 11 января 2010

Проблема в макросе AFX_EXT_CLASS.

#ifdef _AFXEXT
    #define AFX_EXT_CLASS       __declspec(dllexport)
#else
    #define AFX_EXT_CLASS       __declspec(dllimport)
#endif

Расширение dll определяет _AFXEXT, и ваш класс экспортируется, а основное приложение (или обычная dll) не определяет его, поэтому оно импортируется. Но ваше второе расширение dll также определяет _AFXEXT, и ваше объявление класса использует dllimport вместо dllexport, и вы получаете ошибку компоновщика. Решение состоит в том, чтобы создать свой собственный макрос для обеих библиотек и использовать их вместо AFX_EXT_CLASS:

#ifdef EXTENSION_ONE
    #define EXT_CLASS_ONE       __declspec(dllexport)
#else
    #define EXT_CLASS_ONE       __declspec(dllimport)
#endif

Создайте EXTENSION_TWO и EXT_CLASS_TWO для вашего второго dll. Определите EXTENSION_ONE только в вашем первом проекте расширения dll, а EXTENSION_TWO только в вашем втором проекте расширения dll.

...