Panda3D
load_dso.cxx
1 // Filename: load_dso.cxx
2 // Created by: drose (12May00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "load_dso.h"
16 #include "executionEnvironment.h"
17 
18 static Filename resolve_dso(const DSearchPath &path, const Filename &filename) {
19  if (filename.is_local()) {
20  if ((path.get_num_directories()==1)&&(path.get_directory(0)=="<auto>")) {
21  // This is a special case, meaning to search in the same
22  // directory in which libp3dtool.dll, or the exe, was started
23  // from.
25  DSearchPath spath(dtoolpath.get_dirname());
26  return spath.find_file(filename);
27  } else {
28  return path.find_file(filename);
29  }
30  } else {
31  return filename;
32  }
33 }
34 
35 #if defined(WIN32)
36 /* begin Win32-specific code */
37 
38 #define WINDOWS_LEAN_AND_MEAN
39 #include <windows.h>
40 #undef WINDOWS_LEAN_AND_MEAN
41 
42 // Loads in a dynamic library like an .so or .dll. Returns NULL if
43 // failure, otherwise on success. If the filename is not absolute,
44 // searches the path. If the path is empty, searches the dtool
45 // directory.
46 
47 void *
48 load_dso(const DSearchPath &path, const Filename &filename) {
49  Filename abspath = resolve_dso(path, filename);
50  if (!abspath.is_regular_file()) {
51  return NULL;
52  }
53  string os_specific = abspath.to_os_specific();
54 
55  // Try using LoadLibraryEx, if possible.
56  typedef HMODULE (WINAPI *tLoadLibraryEx)(LPCTSTR, HANDLE, DWORD);
57  tLoadLibraryEx pLoadLibraryEx;
58  HINSTANCE hLib = LoadLibrary("kernel32.dll");
59  if (hLib) {
60  pLoadLibraryEx = (tLoadLibraryEx)GetProcAddress(hLib, "LoadLibraryExA");
61  if (pLoadLibraryEx) {
62  return pLoadLibraryEx(os_specific.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
63  }
64  }
65 
66  return LoadLibrary(os_specific.c_str());
67 }
68 
69 bool
70 unload_dso(void *dso_handle) {
71  HMODULE dll_handle = (HMODULE) dso_handle;
72 
73  // true indicates success
74  return (FreeLibrary(dll_handle)!=0);
75 }
76 
77 string
78 load_dso_error() {
79  DWORD last_error = GetLastError();
80 
81  /*
82  LPVOID ptr;
83  if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
84  FORMAT_MESSAGE_FROM_SYSTEM,
85  NULL,
86  last_error,
87  MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
88  (LPTSTR)&ptr,
89  0, NULL))
90  {
91  cout << "ERROR: " << " result = " << (char*) ptr << "\n";
92  LocalFree( ptr );
93  }
94  */
95 
96  switch (last_error) {
97  case 2: return "File not found";
98  case 3: return "Path not found";
99  case 4: return "Too many open files";
100  case 5: return "Access denied";
101  case 14: return "Out of memory";
102  case 18: return "No more files";
103  case 126: return "Module not found";
104  case 127: return "The specified procedure could not be found";
105  case 193: return "Not a valid Win32 application";
106  case 998: return "Invalid access to memory location";
107  }
108 
109  // Some unknown error code.
110  ostringstream errmsg;
111  errmsg << "Unknown error " << last_error;
112  return errmsg.str();
113 }
114 
115 void *
116 get_dso_symbol(void *handle, const string &name) {
117  // Windows puts a leading underscore in front of the symbol name.
118  return (void *)GetProcAddress((HMODULE)handle, name.c_str());
119 }
120 
121 /* end Win32-specific code */
122 
123 #else
124 /* begin Posix code */
125 
126 #if defined(IS_OSX)
127 #include <mach-o/dyld.h>
128 #endif
129 
130 #include <dlfcn.h>
131 
132 void *
133 load_dso(const DSearchPath &path, const Filename &filename) {
134  Filename abspath = resolve_dso(path, filename);
135  if (!abspath.is_regular_file()) {
136  return NULL;
137  }
138  string os_specific = abspath.to_os_specific();
139  return dlopen(os_specific.c_str(), RTLD_NOW | RTLD_GLOBAL);
140 }
141 
142 bool
143 unload_dso(void *dso_handle) {
144  return dlclose(dso_handle)==0;
145 }
146 
147 string
148 load_dso_error() {
149  const char *message = dlerror();
150  if (message != (const char *)NULL) {
151  return std::string(message);
152  }
153  return "No error.";
154 }
155 
156 void *
157 get_dso_symbol(void *handle, const string &name) {
158  return dlsym(handle, name.c_str());
159 }
160 
161 #endif
string get_dirname() const
Returns the directory part of the filename.
Definition: filename.I:424
int get_num_directories() const
Returns the number of directories on the search list.
const Filename & get_directory(int n) const
Returns the nth directory on the search list.
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
static string get_dtool_name()
Returns the name of the libdtool DLL that is used in this program, if it can be determined.
bool is_local() const
Returns true if the filename is local, e.g.
Definition: filename.I:664
bool is_regular_file() const
Returns true if the filename exists and is the name of a regular file (i.e.
Definition: filename.cxx:1389
This class stores a list of directories that can be searched, in order, to locate a particular file...
Definition: dSearchPath.h:32
string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
Definition: filename.cxx:1196
Filename find_file(const Filename &filename) const
Searches all the directories in the search list for the indicated file, in order. ...