Re: [boost] extensions library

Janek, I'll look through the links you sent me and give you a fuller answer.
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.
Here's a bit more info about the library that I have: It is designed in such a way that the data needed for construction of 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 (i.e. these shared objects perhaps weren't even designed when the .exe was compiled). It's kind of difficult to explain, but I'll try to have an example soon. This is the primary thing that made me decide to write this library. I needed this capability. Because of this, you could create a plugin class that is not derived from some interface or other class, and still have it do useful things. It would have to be wrapped in a relatively generic class derived from my boost::extensions::extension class however, in order to load correctly. 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 than my macros, I'll be very happy. I would love a template or inheritance based approach instead, but can't make one work. I'm sorry. On with the code. 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)*/ }; And then in the code that creates it: int main { using namespace boost::extensions; loader my_loader; factory<extension> generic_factory = loader.get_factories<extension>(); } /*Note here that you'd have a problem that this generic_factory would now be able To pull in ANY class that is available from the dlls in the given directory (if no directory is specified, the initial_path (boost::filesystem) is used). That could be bad. I wouldn't do it this way. But it is possible.*/ In that constructor, you could pull the data that you need for construction from the repository. So yes, it would work, like that. As far as being able to pull in a boost::any, I could certainly get it to do that as well, I just don't see a good reason to (I think the above is more than sufficient). Once I put up my documentation on how the repository, requires, and provides concepts work, the above will be more clear. I really will get to that... I already have a functional prototype that compiles and works for sure with Mac OS X (GCC 4) and MSVC 8. It should, theoretically, have no problems on most Unix/Linux or Windows platforms. I have a couple of things I want to get taken care of before I publish it though (that's right: documentation). Jeremy Pack PS No worries. No singletons. In fact, you could have a couple dozen threads using the library, and it would work fine as long as they didn't share objects from the library between them (i.e. each thread needs its own loader object, own repository etc., otherwise some synchronization method would be required). "Janek Kozicki" <janek_listy@wp.pl> wrote in message news:<20061006235420.67bac1f2@absurd>...
Agreed, important area to cover.
For yade (my project) we have written a library for that, the code is here:
Not much documentation, just some comments in the code. It is basically a factory from Andrei Alexandrescu's book "Modern C++", just
a bit tweaked.
That code is short, so you can browse it for hints if you wish.
There is one HUGE mistake there: this library is using a singleton. Singletons hide complexity, don't do that people, I have learned my lesson. I'm currently looking forward to replace it with another more mature and better library, or rewrite yade's library applying 'parametrize from above' solution.
So far, the best candidate for replacement I have currently found is this one:
But you have just lighten up my hopes, because I will be more than happy to use a library for that, which is a part of boost.
I don't know _if_ and _when_ I'll go around to rewrite yade's plugin library, but I should be around to try and help you in writing one. Sadly it is time dependant, so I don't know hom much I will be able to
help.
PS: One question: is it technically possible, to make a plugin class _not_ derived from something (e.g. a class called factorable)? I was wondering about that, and couldn't answer.
-- Janek Kozicki | _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Jeremy, I'm just curious, but have you looked at the extension mechanism the Eclipse defines? That has proven to be successful, although perhaps more heavy-weight than you are proposing. Jeremy

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 |

Janek Kozicki said: (by the date of Sat, 7 Oct 2006 23:25:04 +0200)
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?
To clarify: I'm talking here about problems that virtual inheritance may possibly cause. -- Janek Kozicki |

Janek Kozicki wrote:
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
Why you say "directory," do you mean it searches shared libraries within the directory? This is something I would like to have. The part about searching within the program as well is very important. -Dave

David Greene said: (by the date of Tue, 10 Oct 2006 09:40:54 -0500)
Janek Kozicki wrote:
- inside the currently running program (not a file) - inside all directories declared for search - inside current directory
Why you say "directory," do you mean it searches shared libraries within the directory?
yes, exactly. this is what I have in my project, yade. -- Janek Kozicki |
participants (4)
-
David Greene
-
Janek Kozicki
-
Jeremy Day
-
Jeremy Pack