Docs GODI Archive
Projects Blog Link DB

Search GODI:


More options
File lib/felix/rtl/flx_dynlink.cpp GODI Package apps-felix
 
   flx_dynlink.cpp  
#line 924 "lpsrc/flx_rtl.ipk"
#include "flx_dynlink.hpp"
#ifdef FLX_STATIC_LINK
extern "C" void *create_thread_frame;
extern "C" void *flx_start;
#endif

namespace flx { namespace rtl {

#ifdef MACOSX_NODLCOMPAT
void*
getmachosym(NSModule library, const char* symname)
{
    NSSymbol    sym = NSLookupSymbolInModule(library, symname);
    if(sym)
        return NSAddressOfSymbol(sym);
    return 0;
}

#endif

flx_link_failure_t::flx_link_failure_t(string f, string o, string w) :
  filename(f),
  operation(o),
  what(w)
{}

flx_link_failure_t::~flx_link_failure_t(){}

flx_dynlink_t::~flx_dynlink_t(){}

void flx_dynlink_t::link(char const *fname) throw(flx_link_failure_t)
{
  filename=fname;
#ifndef FLX_STATIC_LINK
//#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(_WIN32)
  SetErrorMode(SEM_NOOPENFILEERRORBOX);  // stop windows showing err dialogues
  library = LoadLibrary(fname);
  if(!library)
    throw flx_link_failure_t(filename,"LoadLibrary","Cannot find dll");
#else
  #ifdef MACOSX_NODLCOMPAT
    NSObjectFileImage            bndl_img;
    NSObjectFileImageReturnCode  res;

    res = NSCreateObjectFileImageFromFile(fname, &bndl_img);

        if(NSObjectFileImageSuccess != res)
      throw flx_link_failure_t(filename, "NSCreateObjectFileImageFromFile",
              "failure to open library");

    // don't merge globals with loader's, load programmatically
    // return on error allows us to continue without being terminated

    unsigned long                link_flags;
    link_flags = NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR;
    library = NSLinkModule(bndl_img, fname, link_flags);

    // even if link failed, we do this
    NSDestroyObjectFileImage(bndl_img);

    // more info can be gleaned about link errors from NSLinkEditError
    if(!library)
      throw flx_link_failure_t(filename, "NSLinkModule", "failed to link");

  #else
  library = dlopen(fname,RTLD_NOW);
  if(!library)
    throw flx_link_failure_t(filename,"dlopen",dlerror());
  #endif
#endif
#endif

  //fprintf(stderr,"File %s dlopened at %p ok\n",fname,library);

  thread_frame_creator = (thread_frame_creator_t)
    DLSYM(library,create_thread_frame);
  if(!thread_frame_creator)
    throw flx_link_failure_t(filename,"dlsym","create_thread_frame");

  //fprintf(stderr,"Thread frame creator found at %p\n",thread_frame_creator);

  start_sym = (start_t)DLSYM(library,flx_start);
  if(!start_sym)
    throw flx_link_failure_t(filename,"dlsym","flx_start");

  //fprintf(stderr,"Start symbol found at %p\n",start_sym);

  refcnt = 1L;

  //fprintf(stderr,"Set refcnt to 1\n");
  try { usr_link(); }
  catch (flx_link_failure_t &) { throw; }
  catch (...) {
    throw flx_link_failure_t
    (
      filename,
      "usr_link()",
      "Unknown user exception"
    );
  }
}

void flx_dynlink_t::unlink()
{
  --refcnt;
  if(refcnt == 0) {
    //fprintf(stderr,"closing library\n");
#ifndef FLX_STATIC_LINK
//#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(_WIN32)
    FreeLibrary(library);
#else
  #ifdef MACOSX_NODLCOMPAT
    NSUnLinkModule(library, NSUNLINKMODULE_OPTION_NONE);
  #else
    dlclose(library);
  #endif
#endif
#endif
  }
}

void flx_dynlink_t::usr_link(){}

flx_libinit_t::~flx_libinit_t(){}

void flx_libinit_t::create
(
  flx_dynlink_t *lib_a,
  flx::gc::generic::collector_t *collector_a,
  int argc,
  char **argv,
  FILE *stdin_,
  FILE *stdout_,
  FILE *stderr_
)
{
  lib = lib_a;
  collector = collector_a;
  thread_frame = lib->thread_frame_creator(
    collector
  );
  //fprintf(stderr,"Incrementing refcnt\n");
  ++lib->refcnt;
  collector->add_root(thread_frame);
  start_proc = lib->start_sym(thread_frame, argc, argv, stdin_,stdout_,stderr_);
  usr_create();
}

void flx_libinit_t::usr_create(){}

void flx_libinit_t::destroy () {
  usr_destroy();
  collector->remove_root(thread_frame);
  //fprintf(stderr,"Decrementing refcnt\n");
  //fprintf(stderr,"Ref cnt=%ld\n",lib->refcnt);
  --lib->refcnt;
  //fprintf(stderr,"Ref cnt=%ld\n",lib->refcnt);
}

void flx_libinit_t::usr_destroy (){}

con_t *flx_libinit_t::bind_proc(void *fn, void *data) {
  typedef con_t *(*binder_t)(void *,void*);
  return ((binder_t)fn)(thread_frame,data);
}

}} // namespaces



This web site is published by Informatikbüro Gerd Stolpmann
Powered by Caml