来自哈德利的C最佳实践:
与C++一样,无论何时在包中使用C代码,都应该在卸载包时卸载DLL:
.onUnload <- function (libpath) {
library.dynam.unload("mypackage", libpath)
}
Run Code Online (Sandbox Code Playgroud)
另一方面,写R扩展甚至没有提到这一点.我可以看到卸载dll是多么礼貌,但这样做似乎会导致一些奇怪的问题,包括加载/卸载/重新加载的包(参见下面的示例).此外,还有一些提及建议可能不需要卸货.来自?library.dynam
:
请注意,是否可以卸载DLL然后重新加载同一文件的修订版本取决于操作系统:请参阅dyn.unload帮助的"值"部分.
虽然这不应该影响未修改的对象.然后是来自R-devel的Brian Ripley的评论:
说了这么多,我的经验是,如果你需要再次加载它,卸载DLL通常没有帮助(这就是为什么例如tcltk不卸载它的DLL).
那么加载C库是否可以接受?我宁愿不必深入研究为什么会发生以下情况(在我开始卸载库之前没有发生).
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’
Run Code Online (Sandbox Code Playgroud)
警告都与alike
功能有关. alike
没有用来卸载它的动态库,并没有发生上述错误.在我实现卸载后,错误开始发生.请注意,data.table 1.9.2
没有卸载其DLL,但其他也不卸载DLL的软件包不会导致此问题. data.table 1.9.4
工作良好.
通常卸载 DLL 是个好主意。它拥有的资源将被完全释放,并且重新加载将不成问题。
在R中,存在R环境的复杂性,因为即使卸载了DLL,也可能在R运行时中留下一些知识。在这种情况下,结果可能是重新加载的DLL库不与旨在理解DLL状态的R变量共享相同的推断状态,从而发生错误。
我认为可以安全地卸载 R 包(DLL 和 R 代码),但让 DLL 保持加载状态会更容易,除非您发现资源使用量特别大。