![]() |
Main Page
Class Hierarchy
Alphabetical List
Compound List
File List
Compound Members
![]() |
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