2014-11-01 8 views
43

Dalla C di Hadley migliore practices:I pacchetti Must R scaricano le librerie dinamiche quando vengono scaricate?

Come con C++, ogni volta che si utilizza il codice C nel pacchetto, è necessario scaricare la DLL quando il pacchetto viene scaricata:

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

Writing R Extensions d'altra parte nemmeno menziona questo. Posso vedere come sarebbe educato scaricare le DLL, ma farlo sembra causare alcuni problemi strani con pacchetti che vengono caricati/scaricati/ricaricati (vedi esempio più avanti). Inoltre, ci sono alcune menzioni che suggeriscono che forse lo scarico non è richiesto. Da ?library.dynam:

Nota che se non è possibile scaricare una DLL e quindi ricaricare una versione rivista dello stesso file è dipende dal sistema operativo: vedere la sezione ‘valore’ di aiuto per dyn.unload.

sebbene questo non dovrebbe interessare oggetti che non sono modificati. Poi c'è questo commento da Brian Ripley in R-devel:

Detto questo, la mia esperienza è che lo scarico del DLL spesso non aiuta se hai bisogno di caricarlo di nuovo (e questo è il motivo per cui ad esempio tcltk non scarica la sua DLL).

Quindi è accettabile lasciare le librerie C caricate? Preferirei non dover indagare sul motivo per cui qualcosa di simile sta succedendo (non è successo prima che avessi iniziato a scaricare le librerie).

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’ 

Gli avvisi sono tutti correlati alle funzioni alike. alike non è stato utilizzato per scaricare le sue librerie dinamiche e gli errori di cui sopra non si sono verificati. Dopo aver implementato lo scarico, gli errori hanno iniziato a verificarsi. Notare che data.table 1.9.2 non ha scaricato le sue DLL, anche se altri pacchetti che non scaricano DLL non hanno causato questo problema. data.table 1.9.4 funziona bene.

+0

So che è la tua domanda ma hai trovato qualche informazione aggiuntiva su questo? – Dason

+0

@Dason, non temendo. Ho anche incontrato [questo problema] (https://github.com/Rdatatable/data.table/issues/990) con 'data.table' che può o non può essere correlato. Inoltre, in realtà non ho avuto questo problema da un po 'di tempo, ma è cambiato troppo per sapere esattamente cosa lo ha risolto. – BrodieG

+1

Strano.Ho l'abitudine di scaricare automaticamente, perché sono stato morso dal debug della versione errata di una DLL che ho dimenticato di scaricare. Il flusso di lavoro era: caricare il pacchetto, trovare bug, correggere, ri-caricare il pacchetto. Ma la DLL non è stata scaricata. Ewps. Quindi il consiglio di Hadley è eccellente per gli sviluppatori. Ma non ho mai visto un problema come il tuo in natura. Roba interessante – Jason

risposta

3

Normalmente lo scaricamento di una DLL sarebbe una buona idea. Le risorse che possiede saranno completamente liberate e il ricaricamento non sarebbe un problema.

In R, c'è la complicazione dell'ambiente R, perché anche se una DLL viene scaricata, potrebbero esserci delle conoscenze lasciate nel runtime R. In questo caso, il risultato potrebbe essere che la libreria DLL caricata non condivide lo stesso stato inferito delle variabili R che sono intese a comprendere lo stato della DLL e quindi si verificano errori.

Penso che sarebbe possibile per un pacchetto R (DLL e codice R) essere scaricato in modo sicuro, ma sarebbe più semplice lasciare le DLL caricate, a meno che non si utilizzi risorse particolarmente pesanti.

+0

Sì. È una pessima idea scaricare una libreria se non hai il pieno controllo di tutti i puntatori a quella libreria. Lo scaricamento di una libreria è un'operazione piuttosto insolita e molti programmi non chiamano mai FreeLibrary(). Come regola generale, l'allocazione delle risorse e la disallocazione in un pacchetto esterno come R è responsabilità del pacchetto stesso _unless esplicitamente specificato nella documentazione_, –

Problemi correlati