Main Page Class Hierarchy Alphabetical List Compound List File List Compound Members

FXDLL.h

Go to the documentation of this file.
00001 /********************************************************************************
00002 *                                                                               *
00003 *               Dynamically linked library loader (DLL loader)                  *
00004 *                                                                               *
00005 *********************************************************************************
00006 * Copyright (C) 2003 by Mathew Robertson.   All Rights Reserved.                *
00007 *********************************************************************************
00008 * This library is free software; you can redistribute it and/or                 *
00009 * modify it under the terms of the GNU Lesser General Public                    *
00010 * License as published by the Free Software Foundation; either                  *
00011 * version 2.1 of the License, or (at your option) any later version.            *
00012 *                                                                               *
00013 * This library is distributed in the hope that it will be useful,               *
00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU             *
00016 * Lesser General Public License for more details.                               *
00017 *                                                                               *
00018 * You should have received a copy of the GNU Lesser General Public              *
00019 * License along with this library; if not, write to the Free Software           *
00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.    *
00021 ********************************************************************************/
00022 #ifndef FXDLL_H
00023 #define FXDLL_H
00024 
00025 namespace FXEX {
00026 
00027 /**
00028  * Dynamically linked library loader which loads the library, based on the filename.
00029  * Includes a macro so as to make dynamic loading of classes simpler than would be otherwise.
00030  *
00031  * Notes:
00032  * When dynamically loading a dll, most OS's automatically load a default library function if
00033  * it it exists (DllMain on Win32, _init on Linux).  The problem is two-fold in that
00034  * a) they are different names for different platforms, b) they are only called once, even
00035  * if they opened a second time, for a second thread (this is a particularly nasty problem
00036  * since the second thread wont initialise and thread specific variables).
00037  *
00038  * To combat this, I have written the class so that if your library contains a C function
00039  * FXDLL_load, it will be called the first time a library is loaded (for a given FXDLL object),
00040  * thus solving the platform problem.  Also, if you load it from a second thread (and thus from
00041  * a second FXDLL objects), it calls FXDLL_load in that thread too (the OS specific auto-exec
00042  * functions dont do this), thus correctly initialising thread specific variables.
00043  *
00044  * Conversly, when you unload the library, if you have a library function called FXDLL_unload,
00045  * it is called before unloading the library (for each FXDLL instance).
00046  */
00047 class FXAPI FXDLL {
00048 protected:
00049   FXString file;
00050   FXString loadedFile;
00051   FXDLLHandle handle;
00052   FXuint refcount;
00053 
00054 protected:
00055   virtual FXDLLHandle loadLibrary(const FXString& filename);
00056   virtual FXDLLHandle unloadLibrary();
00057 
00058 public:
00059   /// create a dll object, using specified filename
00060   FXDLL(const FXString& filename="");
00061 
00062   /// set to new filename - fails silently if library is already loaded.
00063   void setFilename(const FXString& filename);
00064 
00065   /// get the filename
00066   FXString getFilename() const { return file; }
00067 
00068   /// get the name of the file actually loaded
00069   FXString getLoadedFilename() const { return loadedFile; }
00070   
00071   /// open library file
00072   FXbool open();
00073 
00074   /// close library
00075   void close();
00076 
00077   /// indicates if the library is already open
00078   FXbool isOpen();
00079 
00080   /// get handle
00081   FXDLLHandle getHandle() { return handle; }
00082 
00083   /**
00084   * return a pointer to a function
00085   * you will need to do something like this:
00086   *
00087   *   double (*calc)(double a,double b);
00088   *   calc = dll.getFunction("power");
00089   *   result = (*calc)(val1,val2);
00090   */
00091   virtual void* getFunction(const FXString& function);
00092 
00093   /// close library
00094   virtual ~FXDLL();
00095   };
00096 
00097 
00098 /**
00099 * A helper routine for implementing dynamic method loading within a class.
00100 * This implementation uses the method parameters: (FXint,void*) or ()
00101 *
00102 * eg:
00103 * FXDLL_METHOD(FXint,libraryMethod,(void *data,FXint size),const);
00104 * or:
00105 * FXDLL_METHOD(FXString,libraryMethod,(),);
00106 */
00107 #define FXDLL_METHOD(returntype,funcname,params,constness) \
00108   typedef returntype (CALLBACK* functype_##funcname) params constness; \
00109   functype_##funcname dll_##funcname=NULL; \
00110   FXbool isLoaded_##funcname=FALSE;\
00111   returntype funcname params { \
00112     if (!getHandle()) return (returntype)NULL; \
00113     if (!isLoaded_##funcname) { \
00114       dll_##funcname= (functype_##funcname)getFunction(#funcname); \
00115       if (dll_##funcname == NULL) return (returntype)NULL; \
00116       isLoaded_##funcname = TRUE;\
00117       } \
00118     return (dll_##funcname)(params); \
00119     }
00120 
00121 
00122 /**
00123 * A helper routine for implementing dynamic function loading.
00124 * This implementation uses the function parameters : (FXint,void*)  or ()
00125 *
00126 * eg:
00127 * FXDLL_FUNCTION(dllp,FXint,libraryFunction,(void *data,FXint size),const);
00128 * or:
00129 * FXDLL_FUNCTION(pointer_to_FXDLL,FXbool,libraryFunction,(FXString s),);
00130 */
00131 #define FXDLL_FUNCTION(fxdllpointer,returntype,funcname,params,constness) \
00132   typedef returntype (CALLBACK* functype_##funcname) params constness; \
00133   functype_##funcname dll_##funcname=NULL; \
00134   FXbool isLoaded_##funcname=FALSE;\
00135   returntype funcname params { \
00136     if (!fxdllpointer->getHandle()) return (returntype)NULL; \
00137     if (!isLoaded_##funcname) { \
00138       dll_##funcname= (functype_##funcname)fxdllpointer->getFunction(#funcname); \
00139       if (dll_##funcname == NULL) return (returntype)NULL; \
00140       isLoaded_##funcname = TRUE;\
00141       } \
00142     return (dll_##funcname)(params); \
00143     }
00144 
00145 } // namespace FXEX
00146 #endif // FXDLL_H
00147