Глобальные перменные, singleton и DLL
От: jinjik  
Дата: 22.04.11 20:46
Оценка: :)
Есть статическая либа, в которой, реализация некого Singleton:
// SLib.h
Class Signle {
public:
    ~Single() { ... }
    static Single* Instalnce() { ... }
   ... methods ...
protected:
    Single() { ... }
private:
    static Single* inst;
};
// SLib.cpp
// тут реализация методов

Есть код исполняемого файла, в котором подключается данная статическая либа и используется этот сингелтон. Есть некие динамические либы, в которых используются данная статическая либа и этот сингельтон. Эти динамеческие либы используются которые непосредственно из этого же исполняемом файле и больше ни где.

Если я строку
Single* Single::inst = NULL;
помещаю в SLib.cpp, то у меня конструктор сингелтона вызывается при первом дерганье непосредственно из приложения, а также при каждом дерганье либ. Если я эту инициализацию помещаю в код приложения и в каждую из динамических библиотек (убираю из статик либы), то конструктор сингелтона дергается только один раз при первом обращении к сингелтону. То есть в либах его новая инициализация не происходит, используется тот, который инициализировался в основном EXE.
Где почитать по этому поводу, чтобы грамотно было расписано что к чему? гугль толком ничего не дал. Нашел только как другие тыкали пальцем в небо. MSDN — муть сплошлая, ничего не понял, что по этому поводу пишут.
Естественно, что Singleton — частный случай. Интересуют вообще глобальные переменные, статические глобальные, статические внутри одного cpp, статические в статических либах, динамических либах больше 10 лет пишу, а так и не довелось столкнуться ни разу
Re: Глобальные перменные, singleton и DLL
От: Kolobrodin Россия  
Дата: 23.04.11 21:14
Оценка:
Здравствуйте, jinjik, Вы писали:

J>Где почитать по этому поводу, чтобы грамотно было расписано что к чему? гугль толком ничего не дал. Нашел только как другие тыкали пальцем в небо. MSDN — муть сплошлая, ничего не понял, что по этому поводу пишут.

J>Естественно, что Singleton — частный случай. Интересуют вообще глобальные переменные, статические глобальные, статические внутри одного cpp, статические в статических либах, динамических либах больше 10 лет пишу, а так и не довелось столкнуться ни разу

http://stackoverflow.com/questions/1193693/behaviour-of-static-variables-in-dynamically-linked-libraries-c-c
http://stackoverflow.com/questions/2505385/classes-and-static-variables-in-shared-libraries
Неоконченная мысль всегда казалась Шри Япутре слишком
Re: Глобальные перменные, singleton и DLL
От: cpp-coder  
Дата: 23.04.11 22:23
Оценка: +1
Здравствуйте, jinjik, Вы писали:

J>Есть статическая либа, в которой, реализация некого Singleton:

J>
J>// SLib.h
J>Class Signle {
J>public:
J>    ~Single() { ... }
J>    static Single* Instalnce() { ... }
J>   ... methods ...
J>protected:
J>    Single() { ... }
J>private:
J>    static Single* inst;
J>};
J>// SLib.cpp
J>// тут реализация методов

Если в динамических либах всего один класс (например, реализация плагина какого), то почему бы не сделать в них метод, вроде:
void register_app(application& app);
?
И передавать туда ссылку на объект приложения, из которого можно дергать полезные методы, или сам синглтон, или указатель на функцию Instance для получения синглтона?
Так будет решен вопрос единственности в рантайме полезного объекта для всех библиотек + не придется столкнуться с заморочками с динамическими библиотеками для разных платформ.

З.Ы.
А стоит ли в определение класса синглтона помещать статическую переменную, пусть даже private?
Пусть в cpp будет
Single& Single::Instance() 
{
  static Single s;
  return s;
}
Re: Глобальные перменные, singleton и DLL
От: MasterZiv СССР  
Дата: 24.04.11 06:02
Оценка:
On 23.04.2011 0:46, jinjik wrote:

> Если я строку

>
> Single* Single::inst = NULL;
>
> помещаю в SLib.cpp, то у меня конструктор сингелтона вызывается при первом
> дерганье непосредственно из приложения,

Вот так и только так и надо делать.

а также при каждом дерганье либ.

Не должно такого быть. Что значит "дерганье либ" ?


Если я
> эту инициализацию помещаю в код приложения и в каждую из динамических библиотек
> (убираю из статик либы), то конструктор сингелтона дергается только один раз при
> первом обращении к сингелтону.

Так делать НЕЛЬЗЯ. Это нарушение one definition rule.

То есть в либах его новая инициализация не
> происходит, используется тот, который инициализировался в основном EXE.

И не должна. Это глобальная переменная приложения, она одна на всё приложение,
и она должна быть инициализирована (и деинициализирована) только один раз.

> Где почитать по этому поводу, чтобы грамотно было расписано что к чему?


В любом учебнике по С++, даже можно по С. О глобальных переменных.


> Естественно, что Singleton — частный случай.


Singleton собственно тут ни при чём, тут дело в одной переменной,
в данном случае

сlass Signle {
...
static Single* inst;
...
};

Это -- статическая переменная класса, но в общем их правила объявления
и определения такие же, как и у глобальных и статических глобальных переменных
(не класса).

Интересуют вообще глобальные
> переменные, статические глобальные, статические внутри одного cpp, статические в
> статических либах, динамических либах больше 10 лет пишу, а так и не довелось
> столкнуться ни разу

Ну любой учебник хороший по С (глобальные
переменные, статические глобальные, статические внутри одного cpp)
или по С++ (статические переменные класса).

Вообще о Signletone -- можно делать его и так, тогда вообще таких проблем не будет:

// SLib.h
Class Signleton {
public:
     ~Signleton();
     static Signleton* getInstalnce();
    ... methods ...
protected:
     Singleton() { ... }
};
// SLib.cpp
// тут реализация методов

Signleton* Signleton::getInstalnce()
{
     static Singleton inst;

     return &inst;
}
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Глобальные перменные, singleton и DLL
От: Centaur Россия  
Дата: 25.04.11 06:30
Оценка:
Здравствуйте, MasterZiv, Вы писали:

>> Если я строку

>>
>> Single* Single::inst = NULL;
>>
>> помещаю в SLib.cpp, то у меня конструктор сингелтона вызывается при первом
>> дерганье непосредственно из приложения,

MZ>Вот так и только так и надо делать.


>>а также при каждом дерганье либ.


MZ>Не должно такого быть. Что значит "дерганье либ" ?


Почему не должно? Есть три независимых бинарных модуля — foo.exe, bar.dll и quux.dll. Они компилируются и линкуются независимо, поэтому у каждого есть свой собственный экземпляр синглтона. Каждый из них независимо инициализируется при первом использовании, как подобает синглтонам.

>> Если я

>> эту инициализацию помещаю в код приложения и в каждую из динамических библиотек
>> (убираю из статик либы), то конструктор сингелтона дергается только один раз при
>> первом обращении к сингелтону.

MZ>Так делать НЕЛЬЗЯ. Это нарушение one definition rule.


ODR применим в пределах одного бинарника. Что там будет, когда один бинарник динамически подгрузит другой бинарник (в том числе слинкованный из объектников, скомпилированных другими компиляторами, другими версиями того же компилятора, той же версией компилятора с другими опциями) — стандарты C и C++ не регламентируют.

Топикстартеру:

Паттерн «Синглтон» не действует через границу DLL. Хотя бы потому, что основа этого паттерна — «глобальная функция возвращает указатель на экземпляр класса». А классы нельзя использовать через границу DLL.

С точки зрения компилятора и линкера C/C++, динамическая библиотека — это отдельный бинарный модуль. Программа и динамическая библиотека ничего не знают друг о друге, кроме того, что динамическая библиотека экспортирует некоторый набор функций. Они имеют собственные независимые наборы статических переменных.

С другой стороны, статические библиотеки линкуются в один бинарный модуль (программу или динамическую библиотеку). Все глобальные переменные статических библиотек становятся глобальными переменными модуля. Глобальные переменные программы инициализируются перед началом выполнения функции main, прибираются после её завершения. Глобальные переменные динамической библиотеки инициализируются при загрузке библиотеки в DllMain и прибираются при выгрузке тоже в DllMain (из чего следует, что в конструкторах и деструкторах глобальных переменных динамических библиотек нельзя делать ничего интересного).

Переменные, объявленные статическими в C/C++-файле — такие же глобальные переменные, только область их видимости ограничена этим файлом.

Переменные, объявленные статическими внутри функции — такие же глобальные переменные, только область их видимости ограничена этой функцией. Кроме того, инициализироваться они будут не во время загрузки модуля, а при первом проходе через их определения.
Re[3]: Глобальные перменные, singleton и DLL
От: MasterZiv СССР  
Дата: 25.04.11 08:25
Оценка: -1
On 25.04.2011 10:30, Centaur wrote:

> MZ>Не должно такого быть. Что значит "дерганье либ" ?

>
> Почему не должно? Есть три независимых бинарных модуля — foo.exe, bar.dll и
> quux.dll. Они компилируются и линкуются независимо, поэтому у каждого есть свой
> собственный экземпляр синглтона.

Вот этого и не должно быть. Если ещё что-то надо объяснять -- я уже не в силах.

> ODR применим в пределах одного бинарника.


Кто тебе это сказал ? Цитату из устава (блин, стандарта).

> Паттерн «Синглтон» не действует через границу DLL.


Кто тебе сказал ? Цитату из устава (GoF).

> А классы нельзя использовать через границу DLL.


Кто тебе это сказал ? Цитату давай. Я уж не знаю из какого устава.

> С точки зрения компилятора и линкера C/C++, динамическая библиотека — это

> отдельный бинарный модуль. Программа и динамическая библиотека ничего не знают
> друг о друге, кроме того, что динамическая библиотека экспортирует некоторый
> набор функций. Они имеют собственные независимые наборы статических переменных.

Знает. Т.е. может не знать, а может и знать.
В общем промывка мозгов на тему глобальных переменных качественна
только в смысле стирания из головы испытуемого лишней информации.
Posted via RSDN NNTP Server 2.1 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.