Panda3D
 All Classes Functions Variables Enumerations
load_dso.cxx
00001 // Filename: load_dso.cxx
00002 // Created by:  drose (12May00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "load_dso.h"
00016 #include "executionEnvironment.h"
00017 
00018 static Filename resolve_dso(const DSearchPath &path, const Filename &filename) {
00019   if (filename.is_local()) {
00020     if ((path.get_num_directories()==1)&&(path.get_directory(0)=="<auto>")) {
00021       // This is a special case, meaning to search in the same
00022       // directory in which libp3dtool.dll, or the exe, was started
00023       // from.
00024       Filename dtoolpath = ExecutionEnvironment::get_dtool_name();
00025       DSearchPath spath(dtoolpath.get_dirname());
00026       return spath.find_file(filename);
00027     } else {
00028       return path.find_file(filename);
00029     }
00030   } else {
00031     return filename;
00032   }
00033 }
00034 
00035 #if defined(WIN32)
00036 /* begin Win32-specific code */
00037 
00038 #define WINDOWS_LEAN_AND_MEAN
00039 #include <windows.h>
00040 #undef WINDOWS_LEAN_AND_MEAN
00041 
00042 // Loads in a dynamic library like an .so or .dll.  Returns NULL if
00043 // failure, otherwise on success.  If the filename is not absolute,
00044 // searches the path.  If the path is empty, searches the dtool
00045 // directory.
00046 
00047 void *
00048 load_dso(const DSearchPath &path, const Filename &filename) {
00049   Filename abspath = resolve_dso(path, filename);
00050   if (!abspath.is_regular_file()) {
00051     return NULL;
00052   }
00053   string os_specific = abspath.to_os_specific();
00054   
00055   // Try using LoadLibraryEx, if possible.
00056   typedef HMODULE (WINAPI *tLoadLibraryEx)(LPCTSTR, HANDLE, DWORD);
00057   tLoadLibraryEx pLoadLibraryEx;
00058   HINSTANCE hLib = LoadLibrary("kernel32.dll");
00059   if (hLib) {
00060     pLoadLibraryEx = (tLoadLibraryEx)GetProcAddress(hLib, "LoadLibraryExA");
00061     if (pLoadLibraryEx) {
00062       return pLoadLibraryEx(os_specific.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
00063     }
00064   }
00065   
00066   return LoadLibrary(os_specific.c_str());
00067 }
00068 
00069 bool
00070 unload_dso(void *dso_handle) {
00071   HMODULE dll_handle = (HMODULE) dso_handle;
00072 
00073   // true indicates success
00074   return (FreeLibrary(dll_handle)!=0);
00075 }
00076 
00077 string
00078 load_dso_error() {
00079   DWORD last_error = GetLastError();
00080 
00081   /*
00082   LPVOID ptr;
00083   if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
00084                      FORMAT_MESSAGE_FROM_SYSTEM,
00085                      NULL,
00086                      last_error,
00087                      MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
00088                      (LPTSTR)&ptr,
00089                      0, NULL))
00090     {
00091       cout << "ERROR: " << " result = " << (char*) ptr << "\n";
00092       LocalFree( ptr );
00093     }
00094   */
00095 
00096   switch (last_error) {
00097     case 2: return "File not found";
00098     case 3: return "Path not found";
00099     case 4: return "Too many open files";
00100     case 5: return "Access denied";
00101     case 14: return "Out of memory";
00102     case 18: return "No more files";
00103     case 126: return "Module not found";
00104     case 127: return "The specified procedure could not be found";
00105     case 193: return "Not a valid Win32 application";
00106     case 998: return "Invalid access to memory location";
00107   }
00108 
00109   // Some unknown error code.
00110   ostringstream errmsg;
00111   errmsg << "Unknown error " << last_error;
00112   return errmsg.str();
00113 }
00114 
00115 void *
00116 get_dso_symbol(void *handle, const string &name) {
00117   // Windows puts a leading underscore in front of the symbol name.
00118   return (void *)GetProcAddress((HMODULE)handle, name.c_str());
00119 }
00120 
00121 /* end Win32-specific code */
00122 
00123 #else
00124 /* begin Posix code */
00125 
00126 #if defined(IS_OSX)
00127 #include <mach-o/dyld.h>
00128 #endif
00129 
00130 #include <dlfcn.h>
00131 
00132 void *
00133 load_dso(const DSearchPath &path, const Filename &filename) {
00134   Filename abspath = resolve_dso(path, filename);
00135   if (!abspath.is_regular_file()) {
00136     return NULL;
00137   }
00138   string os_specific = abspath.to_os_specific();
00139   return dlopen(os_specific.c_str(), RTLD_NOW | RTLD_GLOBAL);
00140 }
00141 
00142 bool
00143 unload_dso(void *dso_handle) {
00144   return dlclose(dso_handle)==0;
00145 }
00146 
00147 string
00148 load_dso_error() {
00149    const char *message = dlerror();
00150    if (message != (const char *)NULL) {
00151     return std::string(message);
00152   }
00153   return "No error.";
00154 }
00155 
00156 void *
00157 get_dso_symbol(void *handle, const string &name) {
00158   return dlsym(handle, name.c_str());
00159 }
00160 
00161 #endif
 All Classes Functions Variables Enumerations