2 * gmodule.c: dl* functions, glib style
5 * Gonzalo Paniagua Javier (gonzalo@novell.com)
6 * Jonathan Chambers (joncham@gmail.com)
7 * Robert Jordan (robertj@gmx.net)
9 * (C) 2006 Novell, Inc.
10 * (C) 2006 Jonathan Chambers
12 * Permission is hereby granted, free of charge, to any person obtaining
13 * a copy of this software and associated documentation files (the
14 * "Software"), to deal in the Software without restriction, including
15 * without limitation the rights to use, copy, modify, merge, publish,
16 * distribute, sublicense, and/or sell copies of the Software, and to
17 * permit persons to whom the Software is furnished to do so, subject to
18 * the following conditions:
20 * The above copyright notice and this permission notice shall be
21 * included in all copies or substantial portions of the Software.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 #if defined(__native_client__)
36 g_module_open (const gchar *file, GModuleFlags flags)
38 printf("dlopen() not supported on Native Client.\n");
44 g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
53 return "dlopen not supported on Native Client.";
57 g_module_close (GModule *module)
63 g_module_build_path (const gchar *directory, const gchar *module_name)
73 /* For Linux and Solaris, need to add others as we port this */
74 #define LIBPREFIX "lib"
75 #define LIBSUFFIX ".so"
82 g_module_open (const gchar *file, GModuleFlags flags)
88 flags &= G_MODULE_BIND_MASK;
89 if ((flags & G_MODULE_BIND_LAZY) != 0)
91 if ((flags & G_MODULE_BIND_LOCAL) != 0)
94 handle = dlopen (file, f);
98 module = g_new (GModule,1);
99 module->handle = handle;
105 g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
107 if (symbol_name == NULL || symbol == NULL)
110 if (module == NULL || module->handle == NULL)
113 *symbol = dlsym (module->handle, symbol_name);
114 return (*symbol != NULL);
118 g_module_error (void)
124 g_module_close (GModule *module)
127 if (module == NULL || module->handle == NULL)
130 handle = module->handle;
131 module->handle = NULL;
133 return (0 == dlclose (handle));
136 #elif defined (G_OS_WIN32)
140 #define LIBSUFFIX ".dll"
149 g_module_open (const gchar *file, GModuleFlags flags)
152 module = g_malloc (sizeof (GModule));
158 file16 = u8to16(file);
159 module->main_module = FALSE;
160 module->handle = LoadLibrary (file16);
162 if (!module->handle) {
168 module->main_module = TRUE;
169 module->handle = GetModuleHandle (NULL);
176 w32_find_symbol (const gchar *symbol_name)
179 DWORD buffer_size = sizeof (HMODULE) * 1024;
182 modules = (HMODULE *) g_malloc (buffer_size);
187 if (!EnumProcessModules (GetCurrentProcess (), modules,
188 buffer_size, &needed)) {
193 /* check whether the supplied buffer was too small, realloc, retry */
194 if (needed > buffer_size) {
197 buffer_size = needed;
198 modules = (HMODULE *) g_malloc (buffer_size);
203 if (!EnumProcessModules (GetCurrentProcess (), modules,
204 buffer_size, &needed)) {
210 for (i = 0; i < needed / sizeof (HANDLE); i++) {
211 gpointer proc = (gpointer)(intptr_t)GetProcAddress (modules [i], symbol_name);
223 g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
225 if (module == NULL || symbol_name == NULL || symbol == NULL)
228 if (module->main_module) {
229 *symbol = (gpointer)(intptr_t)GetProcAddress (module->handle, symbol_name);
233 *symbol = w32_find_symbol (symbol_name);
234 return *symbol != NULL;
236 *symbol = (gpointer)(intptr_t)GetProcAddress (module->handle, symbol_name);
237 return *symbol != NULL;
242 g_module_error (void)
246 DWORD code = GetLastError ();
248 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL,
249 code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 0, NULL);
258 g_module_close (GModule *module)
263 if (module == NULL || module->handle == NULL)
266 handle = module->handle;
267 main_module = module->main_module;
268 module->handle = NULL;
270 return (main_module ? 1 : (0 == FreeLibrary (handle)));
279 g_module_open (const gchar *file, GModuleFlags flags)
281 g_error ("%s", "g_module_open not implemented on this platform");
286 g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
288 g_error ("%s", "g_module_open not implemented on this platform");
293 g_module_error (void)
295 g_error ("%s", "g_module_open not implemented on this platform");
300 g_module_close (GModule *module)
302 g_error ("%s", "g_module_open not implemented on this platform");
308 g_module_build_path (const gchar *directory, const gchar *module_name)
310 char *lib_prefix = "";
312 if (module_name == NULL)
315 if (strncmp (module_name, "lib", 3) != 0)
316 lib_prefix = LIBPREFIX;
318 if (directory && *directory){
320 return g_strdup_printf ("%s/%s%s" LIBSUFFIX, directory, lib_prefix, module_name);
322 return g_strdup_printf ("%s%s" LIBSUFFIX, lib_prefix, module_name);
325 #endif /* __native_client__ */