15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


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
>
>




| Вернуться в корень Архива |