Extention dll loading order question
Ash Williams -- ash@digitalworkshop.co.uk
Monday, January 27, 1997
Environment: Win95, VC++ 4.2b
Hi,
I'm writing a microsoft extention dll called CommonComponent which
among other things, registers class names in a static Registry
instance, which is declared in my Registry class:
class Registry
{
public: static Registry theRegistry;
public: void registerClass( some parameters );
.
.
.
};
since I need only one of these ever.
Secondly to do automatic registering, I've created a Registering object
which you create statically in classes of your choice, which ultimately
calls Registry::theRegistry.registerClass().
The problem is that I can't guarrentee that Registry::theRegistry is
the first static to be created, which I must have for the static
Registering objects not to cause an access violation.
For now I've made the following class definition:
class Registry
{
public: static Registry* pTheRegistry;
.
.
.
};
on the basis that the first Registering object that gets created turns
on the lights so to speak, ie news up pTheRegistry, by testing if it is
null.
However this will create maintainance problems since any additional
types of static objects in the future which call any member functions
of Registry::pTheRegistry will have to remember to new it up.
Finally to my question then: I noticed that static Registering objects
in a client dll of CommonComponent always get constructed after those
in CommonComponent, so I would like to use this property, since I can
guarrentee that CommonComponent is the client of no other dll.
But am I right in inferring this property - I can't find it in any
documentation, and I won't assume it to be true in case one day another
maintainance programmer compiling the code in a different environment
will get puzzling access violations due to the CommonComponent dll not
being loaded first and its statics therefore left dangling when first
required.
If anyone could confirm or deny the truth of this property or even
suggest an alternative method for forcing the order of static member
construction, I would be ecstatic.
Cheers, Ash
Ken Nicolson -- kenn@owl.co.uk
Tuesday, January 28, 1997
[Mini-digest: 3 responses]
On Mon, 27 Jan 1997 08:12:05 +0000, Ash Williams
wrote:
>Environment: Win95, VC++ 4.2b
>
>Hi,
>
>I'm writing a microsoft extention dll called CommonComponent which=20
>among other things, registers class names in a static Registry=20
>instance, which is declared in my Registry class:
>
>class Registry
>{
> public: static Registry theRegistry;
> public: void registerClass( some parameters );
> .
> .
> .
>};
>
>since I need only one of these ever.
>
>Secondly to do automatic registering, I've created a Registering object=20
>which you create statically in classes of your choice, which ultimately=20
>calls Registry::theRegistry.registerClass().
>
>The problem is that I can't guarrentee that Registry::theRegistry is=20
>the first static to be created, which I must have for the static=20
>Registering objects not to cause an access violation.
This is a perfect job for the Singleton design pattern, from the =
essential
book Design Patterns, by Erich Gamma et al, published by Addison-Wesley,
ISBN 0-201-63361-2. Basically, add the following code to your class:
class Registry
{
public:
static Registry * Instance()
{
if ( m_instance =3D=3D NULL )
m_instance =3D new Registry;
return m_instance;
}
protected:
Registry(); // Stop anyone else creating it
private:
static Registry * m_instance;
// ...
};
// in .cpp file
Registry * Registry::m_instance =3D NULL;
You use it like so:
Registry::Instance()->registerClass();
Thus, you need never worry about order of creation of object, as one will
appear as soon as you need it. If you use this technique with a number of
classes, you can write a template class to implement this.
Buy the Design Patterns book - it's one of the few books that should be =
on
every OO developer's bookshelf, full of useful techniques like this one.
>Cheers, Ash
Ken
PS: Never rely on order of construction of objects - C++ doesn't =
guarantee
anything, and the next version of the soruce code, compiler or operating
system will change it anyway!
-----From: hou@tfn.com (Bing Hou)
Ash,
Alternatively, you can use a global free function(non-memeber function) or a
static function that each of Registry class users calls to obtain a pointer to
the object. The free functio can do something like this.
Registry* GetRegistryClass()
{
static Registry theRegistry;
return &theRegistry;
}
First time the function is called, it creates an object, successive calls will
return a pointer to the object.
Bing Hou
hou@tfn.com
=======================================================================
Be like a postage stamp - stick to one thing until you get there.
- Margaret Carty
=======================================================================
______________________________ Reply Separator _________________________________
Subject: Extention dll loading order question
Author: Ash Williams at Internet
Date: 1/27/97 8:12 AM
Environment: Win95, VC++ 4.2b
Hi,
I'm writing a microsoft extention dll called CommonComponent which
among other things, registers class names in a static Registry
instance, which is declared in my Registry class:
class Registry
{
public: static Registry theRegistry;
public: void registerClass( some parameters );
.
.
.
};
since I need only one of these ever.
Secondly to do automatic registering, I've created a Registering object
which you create statically in classes of your choice, which ultimately
calls Registry::theRegistry.registerClass().
The problem is that I can't guarrentee that Registry::theRegistry is
the first static to be created, which I must have for the static
Registering objects not to cause an access violation.
For now I've made the following class definition:
class Registry
{
public: static Registry* pTheRegistry;
.
.
.
};
on the basis that the first Registering object that gets created turns
on the lights so to speak, ie news up pTheRegistry, by testing if it is
null.
However this will create maintainance problems since any additional
types of static objects in the future which call any member functions
of Registry::pTheRegistry will have to remember to new it up.
Finally to my question then: I noticed that static Registering objects
in a client dll of CommonComponent always get constructed after those
in CommonComponent, so I would like to use this property, since I can
guarrentee that CommonComponent is the client of no other dll.
But am I right in inferring this property - I can't find it in any
documentation, and I won't assume it to be true in case one day another
maintainance programmer compiling the code in a different environment
will get puzzling access violations due to the CommonComponent dll not
being loaded first and its statics therefore left dangling when first
required.
If anyone could confirm or deny the truth of this property or even
suggest an alternative method for forcing the order of static member
construction, I would be ecstatic.
Cheers, Ash
-----From: Jerry Weiler
As far as I know, there is no way to order the creation of global/static
objects. Here's an alternative, somewhat based on the Singleton pattern
in Design Patterns (highly recommended for a lot of neat tricks like
this):
class Registry
{
protected: Registry() { }
public: static Registry* GetInstance();
public: static void registerClass( some parameters );
private: void _registerClass( some parameters );
};
Registry* Registry::GetInstance()
{
static Registry instance;
return &instance;
}
void Registry::registerClass( parameters )
{
GetInstance()->_registerClass( parameters );
}
void Registry::_registerClass( parameters )
{
// do stuff here
}
modify to suit your purposes.
>----------
>From: Ash Williams[SMTP:ash@digitalworkshop.co.uk]
>Sent: Monday, January 27, 1997 3:12 AM
>To: mfc-l@netcom.com
>Cc: ash@digitalworkshop.co.uk
>Subject: Extention dll loading order question
>
>Environment: Win95, VC++ 4.2b
>
>Hi,
>
>I'm writing a microsoft extention dll called CommonComponent which
>among other things, registers class names in a static Registry
>instance, which is declared in my Registry class:
>
>class Registry
>{
> public: static Registry theRegistry;
> public: void registerClass( some parameters );
> .
> .
> .
>};
>
>since I need only one of these ever.
>
>Secondly to do automatic registering, I've created a Registering object
>
>which you create statically in classes of your choice, which ultimately
>
>calls Registry::theRegistry.registerClass().
>
>The problem is that I can't guarrentee that Registry::theRegistry is
>the first static to be created, which I must have for the static
>Registering objects not to cause an access violation.
>
>For now I've made the following class definition:
>
>class Registry
>{
> public: static Registry* pTheRegistry;
> .
> .
> .
>};
>
>on the basis that the first Registering object that gets created turns
>on the lights so to speak, ie news up pTheRegistry, by testing if it is
>
>null.
>
>However this will create maintainance problems since any additional
>types of static objects in the future which call any member functions
>of Registry::pTheRegistry will have to remember to new it up.
>
>Finally to my question then: I noticed that static Registering objects
>in a client dll of CommonComponent always get constructed after those
>in CommonComponent, so I would like to use this property, since I can
>guarrentee that CommonComponent is the client of no other dll.
>
>But am I right in inferring this property - I can't find it in any
>documentation, and I won't assume it to be true in case one day another
>
>maintainance programmer compiling the code in a different environment
>will get puzzling access violations due to the CommonComponent dll not
>being loaded first and its statics therefore left dangling when first
>required.
>
>If anyone could confirm or deny the truth of this property or even
>suggest an alternative method for forcing the order of static member
>construction, I would be ecstatic.
>
>Cheers, Ash
>
>
| Вернуться в корень Архива
|