2014-11-01 112 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