BLLoad.hh

Go to the documentation of this file.
00001 //      BLLoad.hh
00002 /*
00003 This source file is part of G4beamline, http://g4beamline.muonsinc.com
00004 Copyright (C) 2003,2004,2005,2006 by Tom Roberts, all rights reserved.
00005 
00006 This program is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU General Public License
00008 as published by the Free Software Foundation; either version 2
00009 of the License, or (at your option) any later version.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 http://www.gnu.org/copyleft/gpl.html
00017 */
00018 
00019 
00020 #ifndef BLLOAD_HH
00021 #define BLLOAD_HH
00022 
00023 #include <vector>
00024 
00025 #include "globals.hh"
00026 
00027 #if defined(__linux) || defined(__APPLE__)
00028 #include <dlfcn.h>      // for dlopen()
00029 #endif
00030 
00031 typedef void (*VoidFunctionPointer)();
00032 
00033 /** class BLLoad will load a shared object.
00034  *
00035  *  All static object constructors in the shared object are executed
00036  *  while loading, and they can register the resources implemented.
00037  *  The corresponding destructors are probably not executed -- use atexit()
00038  *  or register an appropriate callback with BLManager..
00039  *
00040  *  NOTE: the release 2 build architecture makes this unnecessary (user
00041  *  shared objects are not used). Several .cc files have residual calls
00042  *  to this class, surrounded by #ifdef USE_SHARED_OBJECTS. That may be
00043  *  removed when it's clear this is no longer needed.
00044  **/
00045 class BLLoad {
00046         G4String libname;
00047         void *handle;
00048         static std::vector<BLLoad*> list;
00049         // Constructor.
00050         BLLoad(G4String name, void *p);
00051 public:
00052         /// load() is a static function to load a shared object.
00053         /// It returns a pointer to a BLLoad object, null if error.
00054         /// If no '/' or '\' is present in the name, it will be
00055         /// searched for in the usual way.
00056         /// Normally no extension is used (.so, .dylib, or .dll);
00057         /// this function then appends those extensions in order until a
00058         /// file is found.
00059         /// Loading an already loaded shared object does nothing (no error),
00060         /// returning a new BLLoad object with the same handle.
00061         static BLLoad *load(const G4String &name) {
00062                 G4String n = name;
00063                 void *p = load1(n);
00064                 if(p) return new BLLoad(n,p);
00065                 n = name + ".so";
00066                 p = load1(n);
00067                 if(p) return new BLLoad(n,p);
00068                 n = name + ".dylib";
00069                 p = load1(n);
00070                 if(p) return new BLLoad(n,p);
00071                 n = name + ".dll";
00072                 p = load1(n);
00073                 if(p) return new BLLoad(n,p);
00074 
00075                 return 0;
00076         }
00077 
00078         /// errorString() returns a string describing the previous 
00079         /// error. Static.
00080         static const char *errorString() {
00081 #ifdef WIN32
00082                 return "Unsupported OS";
00083 #endif
00084 #ifdef __CYGWIN__
00085                 return "Unsupported OS";
00086 #endif
00087 #if defined(__linux) || defined(__APPLE__)
00088                 return dlerror(); 
00089 #endif
00090         }
00091 
00092         /// getList() returns the list of BLLoad pointers. Static.
00093         static std::vector<BLLoad*> getList() { return list; }
00094 
00095         /// getName() returns the library name of this DLLoad object.
00096         G4String getName() { return libname; }
00097 
00098 public:
00099         /// getDataSymbol() returns a pointer to a DATA symbol in the shared
00100         /// object. Returns null if not found.
00101         /// The caller must cast the return value to the appropriate type.
00102         void *getDataSymbol(G4String sym) 
00103                 { return dlsym(handle,sym.c_str()); }
00104 
00105         /// getFunctionSymbol() returns a pointer to a FUNCTION symbol in the
00106         /// shared object. Returns null if not found.
00107         /// The caller must cast the return value to the appropriate type.
00108         VoidFunctionPointer getFunctionSymbol(G4String sym) {
00109                 union { void *a; VoidFunctionPointer b; };
00110                 a = dlsym(handle,sym.c_str());
00111                 return b;
00112         }
00113 
00114         // Destructor.
00115         ~BLLoad() { if(handle != 0) dlclose(handle); handle=0; }
00116 private: 
00117         /// load1() is used internally by load()
00118         static void *load1(G4String n) {
00119 
00120 #ifdef WIN32
00121                 return 0;
00122 #endif
00123 #ifdef __CYGWIN__
00124                 return 0;
00125 #endif
00126 #if defined(__linux) || defined(__APPLE__)
00127                 return dlopen(n.c_str(),RTLD_NOW);
00128 #endif
00129         }
00130 };
00131 
00132 #endif // BLLOAD_HH
g4beamline