Boost logo

Boost :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2004-07-27 01:21:48


Reece Dunn wrote:

> >I'm not CORBA expert, but I think it's entirely different beast. To use
> >CORBA object you use stub generated from IDL, how it's related to plugins?
> >While there are some ways to find object dynamically, it's different
> >mechanism from shared libraries, isn't it?
>
> I am not sure how CORBA works. COM generally uses a different mechanism to
> load COM objects via CoCreateInstance, although DirectX exposes creation
> functions that circumvent this. I was thinking about being able to use
> COM/CORBA as a platform for object lifetime and dll lifetime management (as
> well as things like interface extension, etc.).

I know next to nothing about COM, so can't on this idea. In all cases, I think
it's a bit beyond the scope.

> >I though more about at least some kind of map<string, BasePlugin*> which
> > is updated automatically when you load new DLLs.
>
> So the dll implements some function:
>
> __declspec(dllexport) BasePlugin * GetMyPlugin();
>
> so you can do something like:
>
> void load_plugins( map< string, BasePlugin * > & pi )
> {
> for( map< string, BasePlugin * >::iterator i = pi.begin(); i !=
> pi.end(); ++i )
> {
> boost::dll plugin(( *i ).first );
> ( *i ).second = plugin.import< ... >( "GetMyPlugin" );
> }
> }

I haven't said the whole truth ;-) They key of the map is some string name of
plugin, which is not related to its library name. The idea is that you can
write this:

  plugin_map<string, Codegen*> codegens;
  for(unsigned i = 0; i < libraries.size(); ++i)
        codegens.load(libraries[i]);

(where 'libraries' is a vector of libraries filenames). And after that:

  codegens["i386"]->run(........)

> It is possible to keep the DLL in memory until all instances of a class (or
> set of classes) by incrementing/decrementing a global object count variable
> on construction/deconstruction as is done when using COM. You then check
> this variable in the DllCanUnload function.

Yes, I though about it yesterday and decided that some reference counting is
needed. It's probably necessary in more ways:

   dll my_dll("whatever");
   plugin_map<string, Codegen*> codegens;
   codegens.add(my_dll);

   .... heavy hacking ...

   my_dll.reload();

It seems that desire to reload all DLL is valid. In this case, you'd need to
also update 'codegens' because new version of DLL might have changed the list
of exported plugins. So, "dll" class should somehow track all plugin_maps
which depend on it. Or emit boost::signal when it's reloaded.

> You may need some reference counting mechanism to keep the plugin alive,
> but this is not necessary if you load all plugins on startup and release
> them at the end of the run.

This is the simplest approach, but I still thinking about reloading use case.
For example, you have GUI application with plugins. You change some of
plugins and want the reloaded them without restarting the GUI. Possible? Yes.
Critical? Probably not. Can we implement this with little effort?

> It should be possible to implement these facilities in a library, e.g.:
>
> class object_counter
> {
> private:
> static int objectCount = 0;
> public:
> inline int get_object_count(){ return( objectCount ); }
> public:
> inline object_counter(){ ++objectCount; } // make MT aware
> inline ~object_counter(){ --objectCount; } // make MT aware
> };
>
> class reference_counter
> {
> private:
> int refCount;
> public:
> inline void add_ref(){ ++refCount; } // make MT aware
> inline void dec_ref()
> {
> if( --refCount == 0 ) // make MT aware
> {
> delete this;
> }
> }
> public:
> inline reference_counter( int rc ): refCount( rc ){}
> inline ~reference_counter(){}
> };
>
> allowing:
>
> class plugin: public object_counter, public reference_counter, public
> BasePlugin
> {
> // ...
> };
>
> __declspec(dllexport) BOOL DllCanUnload()
> {
> return( object_counter::get_object_count() == 0 );
> }

Do you mean that reference counting should be done by DLL itself? Why not:

   template<class T>
   class plugin_ptr
   {
    public:
       // operator-> and friends
    private:
       T* m_ptr;
       shared_ptr<dll_handle> m_dll;
   }

So, 'dll' won't be deleted until all plugins which use it are dead.

- Volodya


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