1 /////////////////////////////////////////////////////////////////////////////
2 // Name:         dynload.h
3 // Purpose:      Dynamic loading framework
4 // Author:       Ron Lee, David Falkinder, Vadim Zeitlin and a cast of 1000's
5 //               (derived in part from dynlib.cpp (c) 1998 Guilhem Lavaux)
6 // Modified by:
7 // Created:      03/12/01
8 // RCS-ID:       $Id: dynload.h 61872 2009-09-09 22:37:05Z VZ $
9 // Copyright:    (c) 2001 Ron Lee <ron@debian.org>
10 // Licence:      wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12 
13 #ifndef _WX_DYNAMICLOADER_H__
14 #define _WX_DYNAMICLOADER_H__
15 
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19 
20 #include "wx/defs.h"
21 
22 #if wxUSE_DYNAMIC_LOADER
23 
24 #include "wx/dynlib.h"
25 #include "wx/hashmap.h"
26 #include "wx/module.h"
27 
28 class WXDLLIMPEXP_FWD_BASE wxPluginLibrary;
29 
30 
31 WX_DECLARE_STRING_HASH_MAP_WITH_DECL(wxPluginLibrary *, wxDLManifest,
32                                      class WXDLLIMPEXP_BASE);
33 typedef wxDLManifest wxDLImports;
34 
35 // ---------------------------------------------------------------------------
36 // wxPluginLibrary
37 // ---------------------------------------------------------------------------
38 
39 // NOTE: Do not attempt to use a base class pointer to this class.
40 //       wxDL is not virtual and we deliberately hide some of it's
41 //       methods here.
42 //
43 //       Unless you know exacty why you need to, you probably shouldn't
44 //       instantiate this class directly anyway, use wxPluginManager
45 //       instead.
46 
47 class WXDLLIMPEXP_BASE wxPluginLibrary : public wxDynamicLibrary
48 {
49 public:
50 
51     static wxDLImports* ms_classes;  // Static hash of all imported classes.
52 
53     wxPluginLibrary( const wxString &libname, int flags = wxDL_DEFAULT );
54     ~wxPluginLibrary();
55 
56     wxPluginLibrary  *RefLib();
57     bool              UnrefLib();
58 
59         // These two are called by the PluginSentinel on (PLUGGABLE) object
60         // creation/destruction.  There is usually no reason for the user to
61         // call them directly.  We have to separate this from the link count,
62         // since the two are not interchangeable.
63 
64         // FIXME: for even better debugging PluginSentinel should register
65         //        the name of the class created too, then we can state
66         //        exactly which object was not destroyed which may be
67         //        difficult to find otherwise.  Also this code should
68         //        probably only be active in DEBUG mode, but let's just
69         //        get it right first.
70 
RefObj()71     void  RefObj() { ++m_objcount; }
UnrefObj()72     void  UnrefObj()
73     {
74         wxASSERT_MSG( m_objcount > 0, wxT("Too many objects deleted??") );
75         --m_objcount;
76     }
77 
78         // Override/hide some base class methods
79 
IsLoaded()80     bool  IsLoaded() const { return m_linkcount > 0; }
Unload()81     void  Unload() { UnrefLib(); }
82 
83 private:
84 
85     wxClassInfo    *m_before;       // sm_first before loading this lib
86     wxClassInfo    *m_after;        // ..and after.
87 
88     size_t          m_linkcount;    // Ref count of library link calls
89     size_t          m_objcount;     // ..and (pluggable) object instantiations.
90     wxModuleList    m_wxmodules;    // any wxModules that we initialised.
91 
92     void    UpdateClasses();        // Update ms_classes
93     void    RestoreClasses();       // Removes this library from ms_classes
94     void    RegisterModules();      // Init any wxModules in the lib.
95     void    UnregisterModules();    // Cleanup any wxModules we installed.
96 
97     DECLARE_NO_COPY_CLASS(wxPluginLibrary)
98 };
99 
100 
101 class WXDLLIMPEXP_BASE wxPluginManager
102 {
103 public:
104 
105         // Static accessors.
106 
107     static wxPluginLibrary    *LoadLibrary( const wxString &libname,
108                                             int flags = wxDL_DEFAULT );
109     static bool                UnloadLibrary(const wxString &libname);
110 
111         // Instance methods.
112 
wxPluginManager()113     wxPluginManager() : m_entry(NULL) {}
114     wxPluginManager(const wxString &libname, int flags = wxDL_DEFAULT)
115     {
116         Load(libname, flags);
117     }
~wxPluginManager()118     ~wxPluginManager() { if ( IsLoaded() ) Unload(); }
119 
120     bool   Load(const wxString &libname, int flags = wxDL_DEFAULT);
121     void   Unload();
122 
IsLoaded()123     bool   IsLoaded() const { return m_entry && m_entry->IsLoaded(); }
124     void  *GetSymbol(const wxString &symbol, bool *success = 0)
125     {
126         return m_entry->GetSymbol( symbol, success );
127     }
128 
CreateManifest()129     static void CreateManifest() { ms_manifest = new wxDLManifest(wxKEY_STRING); }
ClearManifest()130     static void ClearManifest() { delete ms_manifest; ms_manifest = NULL; }
131 
132 private:
133     // return the pointer to the entry for the library with given name in
134     // ms_manifest or NULL if none
FindByName(const wxString & name)135     static wxPluginLibrary *FindByName(const wxString& name)
136     {
137         const wxDLManifest::iterator i = ms_manifest->find(name);
138 
139         return i == ms_manifest->end() ? NULL : i->second;
140     }
141 
142     static wxDLManifest* ms_manifest;  // Static hash of loaded libs.
143     wxPluginLibrary*     m_entry;      // Cache our entry in the manifest.
144 
145     // We could allow this class to be copied if we really
146     // wanted to, but not without modification.
147     DECLARE_NO_COPY_CLASS(wxPluginManager)
148 };
149 
150 
151 #endif  // wxUSE_DYNAMIC_LOADER
152 #endif  // _WX_DYNAMICLOADER_H__
153 
154