flx_dynlink.hpp

00001 #line 1627 "./lpsrc/flx_rtl.pak"
00002 #ifndef __FLX_DYNLINK_H__
00003 #define __FLX_DYNLINK_H__
00004 #ifndef FLX_RTL
00005 #include "flx_rtl.hpp"
00006 #include "flx_gc.hpp"
00007 #endif
00008 #include <string>
00009 using namespace std;
00010 
00011 // define dynamic library loader stuff, even for static linkage
00012 #if FLX_WIN32
00013   #include <windows.h>
00014   typedef HMODULE LIBHANDLE;
00015   #define FLX_SET_NOLIBRARY(lib) lib=NULL
00016   #define FLX_CHECK_NOLIBRARY(lib) (lib==NULL)
00017   #define FLX_LIB_EXTENSION ".DLL"
00018   #define FLX_DLSYM(x,y) (void*)GetProcAddress(x,#y)
00019   #define FLX_SDLSYM(x,y) (void*)GetProcAddress(x,y)
00020 #elif FLX_MACOSX_NODLCOMPAT
00021   #include <sys/stat.h>
00022   #include <mach-o/dyld.h>
00023   typedef NSModule LIBHANDLE;
00024   #define FLX_SET_NOLIBRARY(lib) lib=NULL
00025   #define FLX_CHECK_NOLIBRARY(lib) (lib==NULL)
00026   #define FLX_LIB_EXTENSION ".dylib"
00027   #define FLX_DLSYM(x, y) flx::rtl::getmachosym(x,"_"#y)
00028   #define FLX_SDLSYM(x, y) flx::rtl::getmachosym(x,(string("_")+string(y)).data())
00029 #else
00030   // UNIX, recent OSX
00031   typedef void *LIBHANDLE;
00032   #define FLX_SET_NOLIBRARY(lib) lib=NULL
00033   #define FLX_CHECK_NOLIBRARY(lib) (lib==NULL)
00034   #if FLX_CYGWIN
00035     #define FLX_LIB_EXTENSION ".dll"
00036   #elif FLX_MACOSX
00037     #define FLX_LIB_EXTENSION ".dylib"
00038   #else
00039     #define FLX_LIB_EXTENSION ".so"
00040   #endif
00041   #include <dlfcn.h>
00042   #define FLX_DLSYM(x,y) dlsym(x,#y)
00043   #define FLX_SDLSYM(x,y) dlsym(x,y)
00044 #endif
00045 
00046 #ifndef FLX_STATIC_LINK
00047   #define DLSYM(x,y) FLX_DLSYM(x,y)
00048   #define SDLSYM(x,y) FLX_SDLSYM(x,y)
00049 #else
00050   #define DLSYM(x,y) (void*)&y
00051   #define SDLSYM(x,y) (throw flx::rtl::link_failure_t("<static link>",y,"dlsym with static link requires name not string")
00052 #endif
00053 
00054 // Utilities to make dynamic linkage and
00055 // initialisation of Felix modules easier
00056 //
00057 // We provide a standard exception to report
00058 // link failure (missing symbol).
00059 //
00060 // We provide a class flx_dynlink_t which
00061 // opens a Felix shared library given a filename,
00062 // and links the mandatory symbols
00063 // The user may derive from this class to add
00064 // linkage for extra symbols
00065 //
00066 // We provide a class flx_libinit_t which
00067 // initialises and terminates a Felix module
00068 // The user may derive from this class to add
00069 // extra initialisation or termination processing.
00070 //
00071 // [Note: the virtuals are *deliberately* private.
00072 // Be sure to make your overrides private too,
00073 // so they cannot be called:
00074 // they're dispatched automatically by wrappers
00075 // defined in the base]
00076 
00077 // must be at global scope, because the users' is
00078 struct thread_frame_t;
00079 
00080 namespace flx { namespace rtl {
00081 
00082 struct RTL_EXTERN flx_link_failure_t;
00083 struct RTL_EXTERN flx_dynlink_t;
00084 struct RTL_EXTERN flx_libinit_t;
00085 
00086 /// Dynamic linkage failure.
00087 
00088 struct RTL_EXTERN flx_link_failure_t : flx_exception_t {
00089   string filename;
00090   string operation;
00091   string what;
00092   flx_link_failure_t(string f, string o, string w);
00093   virtual ~flx_link_failure_t();
00094 };
00095 
00096 RTL_EXTERN LIBHANDLE
00097 flx_load_library(char const *fname);
00098 
00099 RTL_EXTERN LIBHANDLE
00100 flx_load_module(char const *fname);
00101 
00102 /// frame creators.
00103 
00104 typedef thread_frame_t *(*thread_frame_creator_t)
00105 (
00106   flx::gc::generic::collector_t*
00107 );
00108 
00109 /// library initialisation routine.
00110 
00111 typedef con_t *(*start_t)
00112 (
00113   thread_frame_t*,
00114   int,
00115   char **,
00116   FILE*,
00117   FILE*,
00118   FILE*
00119 
00120 );
00121 
00122 typedef con_t *(*main_t)(thread_frame_t*);
00123 
00124 /// dynamic object loader.
00125 
00126 struct RTL_EXTERN flx_dynlink_t
00127 {
00128   // data
00129   LIBHANDLE library;
00130   string filename;
00131   thread_frame_creator_t thread_frame_creator;
00132   start_t start_sym;
00133   main_t main_sym;
00134   long refcnt;
00135 
00136   // routines
00137   void link(char const *filename) throw(flx_link_failure_t);
00138   void unlink();
00139   virtual ~flx_dynlink_t();
00140   flx_dynlink_t();
00141 
00142 private:
00143   // the user should override this procedure to
00144   // link any extra symbols.
00145   // on error, throw a flx_link_failure_t,
00146   // otherwise your exception will be dishonoured
00147   // and a generic link_failure_t thrown anyhow
00148 
00149   flx_dynlink_t(flx_dynlink_t const&); // uncopyable
00150   void operator=(flx_dynlink_t const&); // uncopyable
00151   virtual void usr_link();
00152     // called after mandatory symbols are linked
00153 };
00154 
00155 /// Thread Frame Initialisation.
00156 
00157 struct RTL_EXTERN flx_libinit_t
00158 {
00159   thread_frame_t *thread_frame;
00160   con_t *start_proc;
00161   con_t *main_proc;
00162   flx_dynlink_t *lib;
00163   flx::gc::generic::collector_t *collector;
00164   void create
00165   (
00166     flx_dynlink_t *lib_a,
00167     flx::gc::generic::collector_t *collector_a,
00168     main_t main_sym,
00169     int argc,
00170     char **argv,
00171     FILE *stdin_,
00172     FILE *stdout_,
00173     FILE *stderr_
00174   );
00175 
00176   void destroy ();
00177 
00178   con_t *bind_proc(void *fn, void *data);
00179   virtual ~flx_libinit_t();
00180   flx_libinit_t();
00181 
00182 private:
00183   flx_libinit_t(flx_libinit_t const&);
00184   void operator=(flx_libinit_t const&);
00185   // the user can override these procedures
00186   // to perform any additional initialisation
00187   // and termination required.
00188 
00189   virtual void usr_create();
00190     // called after standard init completes
00191 
00192   virtual void usr_destroy();
00193     // called before standard destroy starts
00194 };
00195 
00196 #if FLX_MACOSX_NODLCOMPAT
00197 void* getmachosym(LIBHANDLE, const char*);
00198 #endif
00199 
00200 }} // namespaces
00201 #endif

Generated on Thu May 29 14:24:58 2008 for Felix by  doxygen 1.5.5