2014-11-01 93 views
43

从哈德利公司的C最好practices必须R程序包卸载时卸载动态库吗?

就像用C++,只要你在你的包中使用的C代码,您应该卸载时,包被卸载DLL:

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

另一方面,Writing R Extensions甚至没有提到这一点。我可以看到卸载dll会有礼貌,但是这样做似乎会导致一些奇怪的问题,导致加载/卸载/重新加载的包(请参阅下面的示例)。此外,还有一些提到建议可能不需要卸载。从?library.dynam

注意它是否可以卸载DLL,然后加载相同的文件的修订版本是依赖于操作系统的:看到的帮助dyn.unload“价值”一节。

虽然这不应该影响未修改的对象。再有就是从Brian Ripley in R-devel此评论:

说了这么多,我的经验是,卸载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’ 

这些警告都与alike功能有关。 alike没有用来卸载它的动态库,并且上述错误没有发生。在我执行卸载后,错误开始发生。请注意,data.table 1.9.2未卸载其DLL,尽管其他程序包也不会卸载DLL并不会导致此问题。 data.table 1.9.4工作正常。

+0

我知道这是你的问题,但你甚至找到关于这方面的任何额外信息? – Dason 2015-04-14 00:08:30

+0

@Dason,不怕。我还用'data.table'碰到了[这个问题](https://github.com/Rdatatable/data.table/issues/990),这可能是也可能不是相关的。另外,我实际上并没有在一段时间内遇到过这个问题,但是太多已经改变到确切地知道是什么修复了它。奇怪的是 – BrodieG 2015-04-14 00:29:06

+1

。我养成了自动卸载的习惯,因为我通过调试我忘记卸载的错误版本的DLL而被咬了。工作流程是:加载包,查找错误,修复,重新加载包。但是DLL没有被卸载。 Ewps。所以哈德利的建议对开发者来说非常好。但我从来没有在野外看到过像你这样的问题。有趣的东西。 – Jason 2016-10-06 03:50:56

回答

3

通常卸载DLL将是一个好主意。它拥有的资源将完全释放,重新加载不会成为问题。

在R中,存在R环境的复杂性,因为即使卸载了DLL,也可能在R运行时留下一些知识。在这种情况下,结果可能是重新加载的DLL库与R变量不共享相同的推断状态,这些R变量旨在了解DLL状态,从而发生错误。

我认为这将是可能的R包(DLL和R码)被安全卸载,但它会更容易让你离开的DLL加载,除非你找到特别重的资源使用情况。

+0

是的。如果您没有完全控制该库的所有指针,那么卸载库是一个非常糟糕的主意。卸载库是一个非常不寻常的操作,许多程序都不会调用FreeLibrary()。作为一个经验法则,像R这样的外部软件包中的资源分配和解除分配是软件包本身的责任_在文档_中明确指定, – 2017-06-13 13:54:13