Panda3D

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