Panda3D
|
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