SEXP attribute_hidden do_dynunload(SEXP call, SEXP op, SEXP args, SEXP env) { char buf[2 * PATH_MAX]; checkArity(op,args); if (!isString(CAR(args)) || LENGTH(CAR(args)) != 1) error(_("character argument expected")); GetFullDLLPath(call, buf, translateChar(STRING_ELT(CAR(args), 0))); if(!DeleteDLL(buf)) error(_("shared object '%s\' was not loaded"), buf); return R_NilValue; }
static DllInfo* AddDLL(const char *path, int asLocal, int now, const char *DLLsearchpath) { HINSTANCE handle; DllInfo *info = NULL; DeleteDLL(path); if(CountDLL == MAX_NUM_DLLS) { strcpy(DLLerror, _("`maximal number of DLLs reached...")); return NULL; } handle = R_osDynSymbol->loadLibrary(path, asLocal, now, DLLsearchpath); if(handle == NULL) { R_osDynSymbol->getError(DLLerror, DLLerrBUFSIZE); return NULL; } info = R_RegisterDLL(handle, path); /* Now look for an initializing routine named R_init_<object name>. If it is present, we call it. It should take a reference to the DllInfo object currently being initialized. */ if(info) { const char *nm = info->name; size_t len = strlen(nm) + 9; char tmp[len]; // R_init_ + underscore + null DllInfoInitCall f; #ifdef HAVE_NO_SYMBOL_UNDERSCORE snprintf(tmp, len, "%s%s","R_init_", info->name); #else snprintf(tmp, len, "_%s%s","R_init_", info->name); #endif f = (DllInfoInitCall) R_osDynSymbol->dlsym(info, tmp); /* If that failed, might have used the package name with . replaced by _ (as . it not valid in symbol names). */ if(!f) { /* This is potentially unsafe in MBCSs, as '.' might be part of a character: but is not in UTF-8 */ for(char *p = tmp; *p; p++) if(*p == '.') *p = '_'; f = (DllInfoInitCall) R_osDynSymbol->dlsym(info, tmp); } if(f) f(info); } return info; }