Boost logo

Boost :

From: Janek Kozicki (janek_listy_at_[hidden])
Date: 2006-10-07 17:25:04


Jeremy Pack said: (by the date of Sat, 7 Oct 2006 11:08:14 -0600)

> Janek,
>
> From looking at the class_loader site, it looks very elegant - it's just
> missing one capability that is, for me, almost the most important.
> one dynamic class may be provided by another dynamic class, and two
> dynamically created classes may communicate or share objects that they
> know about, but that were not known about by the interface in the .exe.

The capability that I would like to have is to be able to create a class
_not_ from a separate file, but also the one that has been declared
somewhere inside the running program. So you can't point at a file and
say "load it". You provide the actual class name, and the extensions
library performs a search in every place it can think of, in following
order:

- inside the currently running program (not a file)
- inside all directories declared for search
- inside current directory

To satisfy this requirement I used a singleton (the simplest solution :( )
After declaring a class (every class in the program) I had to register
it, like that:

class foo : public bar
{
//....
}

REGISTER_FACTORABLE(foo)

where the macro is defined as (simplified version):

#define REGISTER_FACTORABLE(name)\
        inline void* Create##name()\
        {\
                return new name;\
        }\
        const bool registered##name = ClassFactory::instance().registerFactorable( #name , Create##name);

declaring that 'const bool', makes sure that the singleton is informed
about std::string(#name) and a pointer to function that creates the
instance of this class.

And now when I think about it (as my memory about this problem has just
refreshed) - I don't see a way to do that without a singleton :(
Parametrise from above works in such a way, that the object "above" is
first declared, for example inside int main(). Then whatever needs it,
is given this object as an argument. But how to give this object as an
argument to macro, in a place where this object is not accesible?
Moreover - this line 'const bool registered##Name=' is executed _before_
int main(), so this object really does not exist yet, so any forwarding
through some global variable (or singleton ;) will not work.

How to solve that?

> DISCLAIMER:
> Before I write code from the library, I want all of you macro haters to
> prepare to be angry with me. If someone can find a more elegant solution

oh, sometimes macros are neccesary. Especially because they provide
preprocessor # and ## tokens, which are useful in the case of plugins :)
Especially ##

> You could write basically:
> //#define BOOST_EXTENSIONS_CLASS_DECL(classname, superclass, description, requires, provides) ...

> BOOST_EXTENSIONS_CLASS_DECL(class factorable_wrapper,boost::extensions::extension
> , "A Generic Factorable Wrapper"
> , "Requirements\nEach separated by returns or tab"
> , "What this class provides\rAll requirements and provisions are strings")
> // This macro takes care of most everything for declaring
> // the class and making it loadable
> private:
> factorable my_factorable;
> /*take care of initialization of my_factorable in constructor (public or
> private constructor is fine)*/
> };

as I understand, your BOOST_EXTENSIONS_CLASS_DECL() is the equiwalent of
writing a declaration of my plugin class?:

class factorable_wrapper : public superclass
{
//...
}

I feel I did not understand your example, so please correct me.

If I did understand correctly, than what about multiple inheritance or
other weird cases, like this one:

class my_cool_plugin : public cool_foo, virtual cool_bar<std::string>
{
}

BTW: is it even possible to make such class work as a plugin?
 

-- 
Janek Kozicki                                                         |

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk