Re: Единственность переменной в нескольких dll
От: Павел Кузнецов  
Дата: 14.06.04 14:41
Оценка: +2
> Не подскажете, как обеспечить единственность такой переменной (статическая в классе):
>
> template <class T>
> T* CSingleton<T>::m_pInst = NULL;
>

> Это объявление сейчас в заголовочном файле, который используется несколькими DLL. Соответственно, в каждой DLL создаётся по одному экземепляру.

Поместить в одну DLL определения конкретных используемых специализаций, а из других — импортировать.
Posted via RSDN NNTP Server 1.9 alpha
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[6]: Единственность переменной в нескольких dll
От: Кодт Россия  
Дата: 15.06.04 09:05
Оценка: +1
Здравствуйте, Павел Кузнецов, Вы писали:

>> В таком случае как объявить m_pInst? С __declspec(dllimport)? Без этого каждая dll будет искать экземпляр у себя, а с этим dll с экземпляром будет искать его у других. Чую, без макросов тут не обойдётся...


ПК>Да, без макросов тут никуда


Кстати, штатный способ получить грабли:
#ifdef MY_DLL_IMPL
#define MY_DLL_API _declspec(dllexport)
#else
#define MY_DLL_API _declspec(dllimport)
#endif

/////////////////////////////

// .h

class MY_DLL_API CMyClass
{
public:
  static CSomeSingleton& grabli()
  {
    static CSomeSingleton single1_;
    return single1_;
  }

  static CSomeSingleton& rulez();
};

// .cpp

CSomeSingleton& CMyClass::rulez()
{
  static CSomeSingleton single2_;
  return single2_;
}

В пределах одного модуля линкер разберётся, которую из инстанций метода grabli() оставить, и соответственно, single1_. А вот за пределами модуля... оппля.
Причём, заметьте — никаких шаблонов, просто статическая переменная в инлайновой функции.

Выход — не инлайнить.
Перекуём баги на фичи!
Re: Единственность переменной в нескольких dll
От: Аноним  
Дата: 15.06.04 09:50
Оценка: -1
Здравствуйте, чОрт, Вы писали:

О>Не подскажете, как обеспечить единственность такой переменной (статическая в классе):

О>
О>template <class T>
О>T* CSingleton<T>::m_pInst = NULL;
О>

О>Это объявление сейчас в заголовочном файле, который используется несколькими DLL. Соответственно, в каждой DLL создаётся по одному экземепляру.

Как это сделано в ACE:

#define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) template class __declspec (dllexport) SINGLETON_TYPE<CLASS, LOCK>;
#define ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) extern template class SINGLETON_TYPE <CLASS, LOCK>;

При сборке самого dll (с реализацией шаблона) по ifdef'ам подставляете EXPORT, при включении заголовка в другой модуль — IMPORT.
...Спасибо одной известной фирме за такие извращения с библиотеками.
Кстати, есть такой термин даже — "dll hell".

--
Vitaly
Единственность переменной в нескольких dll
От: чОрт Россия  
Дата: 14.06.04 11:57
Оценка:
Не подскажете, как обеспечить единственность такой переменной (статическая в классе):
template <class T>
T* CSingleton<T>::m_pInst = NULL;

Это объявление сейчас в заголовочном файле, который используется несколькими DLL. Соответственно, в каждой DLL создаётся по одному экземепляру.
Re: Единственность переменной в нескольких dll
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 14.06.04 11:59
Оценка:
Здравствуйте, чОрт, Вы писали:

О>Не подскажете, как обеспечить единственность такой переменной (статическая в классе):

О>
О>template <class T>
О>T* CSingleton<T>::m_pInst = NULL;
О>

Может, это поможет?
Re[2]: Единственность переменной в нескольких dll
От: чОрт Россия  
Дата: 14.06.04 12:41
Оценка:
Делаю теперь так:
#pragma data_seg(".SINGL")

//##ModelId=409F996B013A
template <class T>
T* CSingleton<T>::m_pInst = NULL;

#pragma data_seg()
#pragma comment(linker, "/section:.SINGL,rws")

Вылезает вот такое в больших количествах:

LINK : warning LNK4039: section ".SINGL" specified with /SECTION option does not exist


Есть мысль, что с шаблонами такое не прокатит.

З.Ы. На всякий пожарный полная версия singleton.h:
//##ModelId=409F996B0118
template <class T>
class CSingleton
{  
public:
    //##ModelId=409F996B0129
  static bool Create();
    //##ModelId=409F996B012B
  static void Destroy();
    //##ModelId=409F996B012D
  static T* GetInst()
  {
    ASSERT( m_pInst != NULL );
    return m_pInst;
  }

protected:
    //##ModelId=409F996B0137
  CSingleton() {}
    //##ModelId=409F996B0138
  virtual ~CSingleton() { m_pInst=NULL; }

private:
    //##ModelId=409F996B013A
  static T* m_pInst;  
};

#pragma data_seg(".SINGL")

//##ModelId=409F996B013A
template <class T>
T* CSingleton<T>::m_pInst = NULL;

#pragma data_seg()
#pragma  comment(linker, "/section:.SINGL,rws")

//##ModelId=409F996B0129
template <class T>
bool CSingleton<T>::Create()
{
  ASSERT( m_pInst == NULL );
  if ( m_pInst != NULL )
    Destroy();
  
  m_pInst = new T;
  ASSERT( m_pInst != NULL );
  return m_pInst != NULL;
}

//##ModelId=409F996B012B
template <class T>
void CSingleton<T>::Destroy()
{
  ASSERT( m_pInst != NULL );
  
  if( m_pInst != NULL )
    delete m_pInst;
}
Re[3]: Единственность переменной в нескольких dll
От: чОрт Россия  
Дата: 14.06.04 12:55
Оценка:
Так-так... Наткнулся в соседней ветке на это
Автор: Batiskaf
Дата: 14.06.04
. Будет время — попробую. В правильном направлении копаю?
Re[4]: Единственность переменной в нескольких dll
От: Павел Кузнецов  
Дата: 14.06.04 14:37
Оценка:
> Так-так... Наткнулся в соседней ветке на это
Автор: Batiskaf
Дата: 14.06.04
. Будет время — попробую. В правильном направлении копаю?


От замены переменной функцией в плане DLL ничего не изменится.
Posted via RSDN NNTP Server 1.9 alpha
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: Единственность переменной в нескольких dll
От: чОрт Россия  
Дата: 14.06.04 15:35
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Поместить в одну DLL определения конкретных используемых специализаций, а из других — импортировать.


Да, похоже придётся так и сделать. А в идеале хотелось бы отнаследовать класс от CSingleton и получить свойства синглтона с минимальными добавками. А так придётся лезть в другую dll, чтобы объявить там экзэмпляр. Блин!
Re[3]: Единственность переменной в нескольких dll
От: Павел Кузнецов  
Дата: 14.06.04 15:39
Оценка:
> ПК>Поместить в одну DLL определения конкретных используемых специализаций, а из других — импортировать.

> Да, похоже придётся так и сделать. А в идеале хотелось бы отнаследовать класс от CSingleton и получить свойства синглтона с минимальными добавками. А так придётся лезть в другую dll, чтобы объявить там экзэмпляр. Блин!


Можно не лезть в другую DLL, а делать это все в DLL, в которой определен класс, унаследованный от CSingleton.
Posted via RSDN NNTP Server 1.9 alpha
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[4]: Единственность переменной в нескольких dll
От: чОрт Россия  
Дата: 14.06.04 15:55
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Можно не лезть в другую DLL, а делать это все в DLL, в которой определен класс, унаследованный от CSingleton.


В таком случае как объявить m_pInst? С __declspec(dllimport)? Без этого каждая dll будет искать экземпляр у себя, а с этим dll с экземпляром будет искать его у других. Чую, без макросов тут не обойдётся...
Re[5]: Единственность переменной в нескольких dll
От: Павел Кузнецов  
Дата: 14.06.04 16:19
Оценка:
> В таком случае как объявить m_pInst? С __declspec(dllimport)? Без этого каждая dll будет искать экземпляр у себя, а с этим dll с экземпляром будет искать его у других. Чую, без макросов тут не обойдётся...

Да, без макросов тут никуда
Posted via RSDN NNTP Server 1.9 alpha
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: Единственность переменной в нескольких dll
От: Sir Wiz Россия  
Дата: 23.06.04 13:36
Оценка:
Здравствуйте, чОрт, Вы писали:

О>Не подскажете, как обеспечить единственность такой переменной (статическая в классе):

О>
О>template <class T>
О>T* CSingleton<T>::m_pInst = NULL;
О>

О>Это объявление сейчас в заголовочном файле, который используется несколькими DLL. О>Соответственно, в каждой DLL создаётся по одному экземепляру.
Если делаем DLL, значит работаем под виндами, значит можно не погнушаться использованием mapped file. Хранить в нём разделяемые переменные ваших dll.

И вопрос. Я часто именно так и делаю. Найдутся ли какие-либо противопоказания у ALL?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.