From: David Shen on
Hi,

Whenever a dll is loaded into a process, the 'DllMain' will be called. I
want to know that if there's a global variable of an instance of a
class, say class CSingle, will the instantiation of this variable be
guaranteed to be performed once? E.g.

CSingle _single;

BOOL WINAPI DllMain(...)
{
....
}

Will the constructor of _single be called only once, no matter how many
times this dll being loaded?

Because in .Net framework, the CLR loader would make sure that the
constructor of a 'static' member is called only once. This made easy to
implement the 'Singleton' pattern.


Thanks,
David
From: Ulrich Eckhardt on
David Shen wrote:
> Whenever a dll is loaded into a process, the 'DllMain' will be called.

No, it's called when loaded, unloaded and when a thread is started or
terminated.

> I want to know that if there's a global variable of an instance of a
> class, say class CSingle, will the instantiation of this variable be
> guaranteed to be performed once?

Yes, this variable will be instantiated exactly once in this process. Note
that that is independent of whether you are using a DllMain() or not. In
general, it is a global variable like any other.

> E.g.
>
> CSingle _single;
>
> BOOL WINAPI DllMain(...)
> {
> ...
> }
>
> Will the constructor of _single be called only once, no matter how many
> times this dll being loaded?

No. It will exist at most once per process. If you load and unload a DLL, it
will be created and destroyed. If you load the DLL twice into the same
process, it will only be created once. If you load it into two different
processes, it will be created for each of them.

BTW: names with a leading underscore are partially reserved, don't use them!

> Because in .Net framework, the CLR loader would make sure that the
> constructor of a 'static' member is called only once. This made easy to
> implement the 'Singleton' pattern.

Hmmm. Problems with globals usually come up when either they start threads
or when they access other globals, which may or may not have been created
already. Storing singletons in variables that need no constructor (e.g.
pointers) and then creating them on demand is much safer (see also
the 'static initialisation order fiasco' in the C++ FAQ at parashift's).
However, creating singletons in a thread-safe and initialisation-safe way
is actually rather complicated, as discussions on clc++m or the Boost
mailinglist show.

Uli

--
Sator Laser GmbH
Geschäftsführer: Michael Wöhrmann, Amtsgericht Hamburg HR B62 932

From: Jeff Henkels on
"Ulrich Eckhardt" <eckhardt(a)satorlaser.com> wrote in message
news:qgo3e5-01n.ln1(a)satorlaser.homedns.org...
> David Shen wrote:
>> Whenever a dll is loaded into a process, the 'DllMain' will be called.
>
> No, it's called when loaded, unloaded and when a thread is started or
> terminated.

That's the normal case. To be thorough, one should note that if DllMain
calls DisableThreadLibraryCalls() at DLL_PROCESS_ATTACH time, it will not be
called for DLL_THREAD_ATTACH or DLL_THREAD_DETACH. This can be useful in
some situations.


From: David Shen on
Ulrich Eckhardt wrote:
> David Shen wrote:
>> Because in .Net framework, the CLR loader would make sure that the
>> constructor of a 'static' member is called only once. This made easy to
>> implement the 'Singleton' pattern.
>
> Hmmm. Problems with globals usually come up when either they start threads
> or when they access other globals, which may or may not have been created
> already. Storing singletons in variables that need no constructor (e.g.
> pointers) and then creating them on demand is much safer (see also
> the 'static initialisation order fiasco' in the C++ FAQ at parashift's).
> However, creating singletons in a thread-safe and initialisation-safe way
> is actually rather complicated, as discussions on clc++m or the Boost
> mailinglist show.
>
> Uli
>


So, if I can still use this mechanism to implement 'Singleton' within a
process scope, right? To do global singleton, I will still need to us
the PV primitives, like lock and critical sections, right?


Thanks,
David
From: Ulrich Eckhardt on
David Shen wrote:
> Ulrich Eckhardt wrote:
>> David Shen wrote:
>>> Because in .Net framework, the CLR loader would make sure that the
>>> constructor of a 'static' member is called only once. This made easy to
>>> implement the 'Singleton' pattern.
>>
>> Hmmm. Problems with globals usually come up when either they start
>> threads or when they access other globals, which may or may not have been
>> created already. Storing singletons in variables that need no constructor
>> (e.g. pointers) and then creating them on demand is much safer (see also
>> the 'static initialisation order fiasco' in the C++ FAQ at parashift's).
>> However, creating singletons in a thread-safe and initialisation-safe way
>> is actually rather complicated, as discussions on clc++m or the Boost
>> mailinglist show.
>>
>> Uli
>>
>
>
> So, if I can still use this mechanism to implement 'Singleton' within a
> process scope, right?

Yes, a global can be used as singleton.

> To do global singleton, I will still need to us the PV primitives, like
> lock and critical sections, right?

I guess that with 'global' you mean 'system-wide' (all users) or
maybe 'session-wide' (current user). For that you first need to make sure
that you can actually talk to the same object from different processes. You
could use shared memory or a dedicated server process for that. Of course,
this also requires some kind of synchronisation, but how that is done
doesn't actually matter.

Uli

--
Sator Laser GmbH
Geschäftsführer: Michael Wöhrmann, Amtsgericht Hamburg HR B62 932