flx_dynlink.hpp

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

Generated on Mon Dec 11 14:48:23 2006 for Felix by  doxygen 1.5.1