| File include/flx_dynlink.hpp |
GODI Package
apps-felix |
#line 755 "lpsrc/flx_rtl.ipk"
#ifndef FLX_DYNLINK
#define FLX_DYNLINK
#ifndef FLX_RTL
#include "flx_rtl.hpp"
#include "flx_gc.hpp"
#endif
#include <string>
using namespace std;
// define the type of a library handle: needed even for static linkage
//#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(_WIN32)
#include <windows.h>
typedef HMODULE LIBHANDLE;
#else
#ifdef MACOSX_NODLCOMPAT
#include <mach-o/dyld.h>
typedef NSModule LIBHANDLE;
#else
typedef void *LIBHANDLE;
#endif
#endif
#ifndef FLX_STATIC_LINK
//#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(_WIN32)
#define DLSYM(x,y) (void*)GetProcAddress(x,#y)
#define SDLSYM(x,y) (void*)GetProcAddress(x,y)
#else
#ifdef MACOSX_NODLCOMPAT
//#include <mach-o/dyld.h>
#define DLSYM(x, y) flx::rtl::getmachosym(x,"_"#y)
#define SDLSYM(x, y) flx::rtl::getmachosym(x,(string("_")+string(y)).data())
#else
#include <dlfcn.h>
#define DLSYM(x,y) dlsym(x,#y)
#define SDLSYM(x,y) dlsym(x,y)
#endif
#endif
#else
#define DLSYM(x,y) (void*)&y
#define SDLSYM(x,y) (throw flx::rtl::link_failure_t("<static link>",y,"dlsym with static link requires name not string")
#endif
// Utilities to make dynamic linkage and
// initialisation of Felix modules easier
//
// We provide a standard exception to report
// link failure (missing symbol).
//
// We provide a a class flx_dynlink_t which
// opens a Felix shared library given a filename,
// and links the mandatory symbols
// The user may derive from this class to add
// linkage for extra symbols
//
// We provide a class flx_libinit_t which
// initialises and terminates a Felix module
// The user may derive from this class to add
// extra initialisation or termination processing.
//
// [Note: the virtuals are *deliberately* private.
// Be sure to make your overrides private too,
// so they cannot be called:
// they're dispatched automatically by wrappers
// defined in the base]
// must be at global scope, because the users' is
struct thread_frame_t;
namespace flx { namespace rtl {
struct FLX_RTL_EXTERN flx_link_failure_t;
struct FLX_RTL_EXTERN flx_dynlink_t;
struct FLX_RTL_EXTERN flx_libinit_t;
struct FLX_RTL_EXTERN flx_link_failure_t {
string filename;
string operation;
string what;
flx_link_failure_t(string f, string o, string w);
virtual ~flx_link_failure_t();
};
// frame creators
typedef thread_frame_t *(*thread_frame_creator_t)
(
flx::gc::generic::collector_t*
);
// library initialisation routine
typedef con_t *(*start_t)
(
thread_frame_t*,
int,
char **,
FILE*,
FILE*,
FILE*
);
struct FLX_RTL_EXTERN flx_dynlink_t
{
// data
LIBHANDLE library;
string filename;
thread_frame_creator_t thread_frame_creator;
start_t start_sym;
long refcnt;
// routines
void link(char const *filename) throw(flx_link_failure_t);
void unlink();
virtual ~flx_dynlink_t();
private:
// the user should override this procedure to
// link any extra symbols.
// on error, throw a flx_link_failure_t,
// otherwise your exception will be dishonoured
// and a generic link_failure_t thrown anyhow
virtual void usr_link();
// called after mandatory symbols are linked
};
struct FLX_RTL_EXTERN flx_libinit_t
{
thread_frame_t *thread_frame;
con_t *start_proc;
flx_dynlink_t *lib;
flx::gc::generic::collector_t *collector;
void create
(
flx_dynlink_t *lib_a,
flx::gc::generic::collector_t *collector_a,
int argc,
char **argv,
FILE *stdin_,
FILE *stdout_,
FILE *stderr_
);
void destroy ();
con_t *bind_proc(void *fn, void *data);
virtual ~flx_libinit_t();
private:
// the user can override these procedures
// to perform any additional initialisation
// and termination required.
virtual void usr_create();
// called after standard init completes
virtual void usr_destroy();
// called before standard destroy starts
};
#ifdef MACOSX_NODLCOMPAT
void* getmachosym(LIBHANDLE, const char*);
#endif
}} // namespaces
#endif