Must R Packages Unload Dynamic Libraries When They

2020-05-29 13:31发布

问题:

From Hadley's C best practices:

Like with C++, whenever you use C code in your package, you should unload the DLL when the package is unloaded:

.onUnload <- function (libpath) {
  library.dynam.unload("mypackage", libpath)
}

Writing R Extensions on the other hand doesn't even mention this. I can see how it would be polite to unload the dlls, but doing so seems to cause some weird problems for me with packages that are loaded/unloaded/reloaded (see example further down). Additionally, there are some mentions that suggest maybe unloading isn't required. From ?library.dynam:

Note that whether or not it is possible to unload a DLL and then reload a revised version of the same file is OS-dependent: see the ‘Value’ section of the help for dyn.unload.

though this shouldn't affect objects that are not modified. Then there is this comment from Brian Ripley in R-devel:

Having said all that, my experience is that unloading the DLL often does not help if you need to load it again (and that is why e.g. tcltk does not unload its DLL).

So is it acceptable to leave the C libraries loaded? I would prefer not to have to dig into why stuff like the below is happening (did not happen before I started unloading libraries).

R version 3.1.1 (2014-07-10)
Platform: x86_64-apple-darwin13.1.0 (64-bit)

> library(alike)       # install_github("brodieg/alike", ref="fdaa578e"), if you're curious
> library(data.table)
data.table 1.9.2  For help type: help("data.table")
> detach("package:data.table", unload=T)
> detach("package:alike", unload=T)
> library(alike)
> library(data.table)
Error : .onLoad failed in loadNamespace() for 'data.table', details:
  call: address(x)
  error: object 'Caddress' not found
In addition: Warning messages:
1: In FUN(X[[9L]], ...) :
  failed to assign RegisteredNativeSymbol for alike to alike since alike is already defined in the ‘data.table’ namespace
2: In FUN(X[[9L]], ...) :
  failed to assign RegisteredNativeSymbol for typeof to typeof since typeof is already defined in the ‘data.table’ namespace
3: In FUN(X[[9L]], ...) :
  failed to assign RegisteredNativeSymbol for type_alike to type_alike since type_alike is already defined in the ‘data.table’ namespace
Error: package or namespace load failed for ‘data.table’

The warnings are all related to alike functions. alike did not use to unload its dynamic libraries, and the above errors did not happen. After I implemented unloading the errors started happening. Note that data.table 1.9.2 did not unload its DLLs, though other packages that also don't unload DLLs didn't cause this problems. data.table 1.9.4 works fine.

回答1:

Normally unloading a DLL would be a good idea. The resources it owns, would be completely freed, and re-loading would not be an issue.

In R, there is the complication of the R environment, because even if a DLL is unloaded, there may be some knowledge left behind in the R runtime. In this case, the result may be that the re-loaded DLL library does not share the same inferred state as the R variables which are intended to understand the DLL state, and thus errors occur.

I think it would be possible for an R package (DLL and R code) to be safely unloaded, but it would be easier for you to leave the DLLs loaded, unless you find particularly heavy resource usage.



标签: c r dll packages