int sys_load_lib(t_canvas *canvas, const char *classname) { int dspstate = canvas_suspend_dsp(); struct _loadlib_data data; data.canvas = canvas; data.ok = 0; if (sys_onloadlist(classname)) { verbose(1, "%s: already loaded", classname); return (1); } /* if classname is absolute, try this first */ if (sys_isabsolutepath(classname)) { /* this is just copied from sys_open_absolute() LATER avoid code duplication */ char dirbuf[MAXPDSTRING], *z = strrchr(classname, '/'); int dirlen; if (!z) return (0); dirlen = (int)(z - classname); if (dirlen > MAXPDSTRING-1) dirlen = MAXPDSTRING-1; strncpy(dirbuf, classname, dirlen); dirbuf[dirlen] = 0; data.classname=classname+(dirlen+1); sys_loadlib_iter(dirbuf, &data); } data.classname = classname; if(!data.ok) canvas_path_iterate(canvas, (t_canvas_path_iterator)sys_loadlib_iter, &data); /* if loaders failed so far, we try a last time without a PATH * let the loaders search wherever they want */ if (!data.ok) sys_loadlib_iter(0, &data); if(data.ok) sys_putonloadlist(classname); canvas_resume_dsp(dspstate); return data.ok; }
static int sys_do_load_lib(t_canvas *canvas, char *objectname) { char symname[MAXPDSTRING], filename[MAXPDSTRING], dirbuf[MAXPDSTRING], *classname, *nameptr, altsymname[MAXPDSTRING]; void *dlobj; t_xxx makeout = NULL; int i, hexmunge = 0, fd; #ifdef _WIN32 HINSTANCE ntdll; #endif if (classname = strrchr(objectname, '/')) classname++; else classname = objectname; if (sys_onloadlist(objectname)) { post("%s: already loaded", objectname); return (1); } for (i = 0, nameptr = classname; i < MAXPDSTRING-7 && *nameptr; nameptr++) { char c = *nameptr; if ((c>='0' && c<='9') || (c>='A' && c<='Z')|| (c>='a' && c<='z' )|| c == '_') { symname[i] = c; i++; } /* trailing tilde becomes "_tilde" */ else if (c == '~' && nameptr[1] == 0) { strcpy(symname+i, "_tilde"); i += strlen(symname+i); } else /* anything you can't put in a C symbol is sprintf'ed in hex */ { sprintf(symname+i, "0x%02x", c); i += strlen(symname+i); hexmunge = 1; } } symname[i] = 0; if (hexmunge) { memmove(symname+6, symname, strlen(symname)+1); strncpy(symname, "setup_", 6); } else strcat(symname, "_setup"); #if 0 fprintf(stderr, "lib: %s\n", classname); #endif /* try looking in the path for (objectname).(sys_dllextent) ... */ if ((fd = canvas_open(canvas, objectname, sys_dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; /* same, with the more generic sys_dllextent2 */ if ((fd = canvas_open(canvas, objectname, sys_dllextent2, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; /* next try (objectname)/(classname).(sys_dllextent) ... */ strncpy(filename, objectname, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, classname, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; if ((fd = canvas_open(canvas, filename, sys_dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; if ((fd = canvas_open(canvas, filename, sys_dllextent2, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; return (0); gotone: close(fd); class_set_extern_dir(gensym(dirbuf)); /* rebuild the absolute pathname */ strncpy(filename, dirbuf, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, nameptr, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; #ifdef HAVE_LIBDL dlobj = dlopen(filename, RTLD_NOW | RTLD_GLOBAL); if (!dlobj) { post("%s: %s", filename, dlerror()); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)dlsym(dlobj, symname); /* fprintf(stderr, "symbol %s\n", symname); */ #endif #ifdef _WIN32 sys_bashfilename(filename, filename); ntdll = LoadLibrary(filename); if (!ntdll) { post("%s: couldn't load", filename); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)GetProcAddress(ntdll, symname); #endif if (!makeout) { post("load_object: Symbol \"%s\" not found", symname); class_set_extern_dir(&s_); return 0; } (*makeout)(); class_set_extern_dir(&s_); sys_putonloadlist(objectname); return (1); }
static int sys_do_load_lib(t_canvas *canvas, char *objectname) { char symname[MAXPDSTRING], filename[MAXPDSTRING], dirbuf[MAXPDSTRING], *classname, *nameptr, altsymname[MAXPDSTRING]; void *dlobj; t_xxx makeout = NULL; int i, hexmunge = 0, fd; #ifdef _WIN32 HINSTANCE ntdll; #endif if (classname = strrchr(objectname, '/')) classname++; else classname = objectname; if (sys_onloadlist(objectname)) { post("%s: already loaded", objectname); return (1); } for (i = 0, nameptr = classname; i < MAXPDSTRING-7 && *nameptr; nameptr++) { char c = *nameptr; if ((c>='0' && c<='9') || (c>='A' && c<='Z')|| (c>='a' && c<='z' )|| c == '_') { symname[i] = c; i++; } /* trailing tilde becomes "_tilde" */ else if (c == '~' && nameptr[1] == 0) { strcpy(symname+i, "_tilde"); i += strlen(symname+i); } else /* anything you can't put in a C symbol is sprintf'ed in hex */ { sprintf(symname+i, "0x%02x", c); i += strlen(symname+i); hexmunge = 1; } } symname[i] = 0; if (hexmunge) { memmove(symname+6, symname, strlen(symname)+1); strncpy(symname, "setup_", 6); } else strcat(symname, "_setup"); #if 0 fprintf(stderr, "lib: %s\n", classname); #endif /* try looking in the path for (objectname).(sys_dllextent) ... */ if ((fd = canvas_open(canvas, objectname, sys_dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; /* same, with the more generic sys_dllextent2 */ if ((fd = canvas_open(canvas, objectname, sys_dllextent2, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; /* next try (objectname)/(classname).(sys_dllextent) ... */ strncpy(filename, objectname, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, classname, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; if ((fd = canvas_open(canvas, filename, sys_dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; if ((fd = canvas_open(canvas, filename, sys_dllextent2, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; return (0); gotone: close(fd); class_set_extern_dir(gensym(dirbuf)); /* rebuild the absolute pathname */ strncpy(filename, dirbuf, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, nameptr, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; #ifdef _WIN32 { char dirname[MAXPDSTRING], *s, *basename; sys_bashfilename(filename, filename); /* set the dirname as DllDirectory, meaning in the path for loading other DLLs so that dependent libraries can be included in the same folder as the external. SetDllDirectory() needs a minimum supported version of Windows XP SP1 for SetDllDirectory, so WINVER must be 0x0502 */ strncpy(dirname, filename, MAXPDSTRING); s = strrchr(dirname, '\\'); basename = s; if (s && *s) *s = '\0'; if (!SetDllDirectory(dirname)) error("Could not set '%s' as DllDirectory(), '%s' might not load.", dirname, basename); /* now load the DLL for the external */ ntdll = LoadLibrary(filename); if (!ntdll) { post("%s: couldn't load", filename); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)GetProcAddress(ntdll, symname); if (!makeout) makeout = (t_xxx)GetProcAddress(ntdll, "setup"); SetDllDirectory(NULL); /* reset DLL dir to nothing */ } #elif defined HAVE_LIBDL dlobj = dlopen(filename, RTLD_NOW | RTLD_GLOBAL); if (!dlobj) { post("%s: %s", filename, dlerror()); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)dlsym(dlobj, symname); if(!makeout) makeout = (t_xxx)dlsym(dlobj, "setup"); #else #warning "No dynamic loading mechanism specified, libdl or WIN32 required for loading externals!" #endif if (!makeout) { post("load_object: Symbol \"%s\" not found", symname); class_set_extern_dir(&s_); return 0; } (*makeout)(); class_set_extern_dir(&s_); sys_putonloadlist(objectname); return (1); }