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