2011-07-20 15 views
5

Aşağıdaki kodda, foo_new() çağrısıyla foo nesnesi oluşturulur ve nesneye bir dış işaretçiyi döndürür. Sonraki hesaplamalar ptr_foo geçirilerek gerçekleştirilir. Nesne en sonunda foo_free (foo * X) 'a açık bir çağrı ile serbest bırakılır. Tüm hesaplamalar libfoo tarafından gerçekleştirilir.R .call() interface ve EXTPTRSXP: Harici olarak ayrılmış nesnelerle PROTECT/UNPROTECT öğesinin anlaşılması

ptr_foo'nun yaratılmış olması, foo nesnesi içindeki tüm dinamik olarak ayrılmış alanların otomatik olarak korunacağı anlamına mı geliyor? Ya da, "bar" gibi alanların çöp toplayıcı tarafından uzaklaştırılması mümkün mü?

SEXP foo_new (SEXP n) { 
    SEXP ptr_foo; 
    foo *X = (foo*) foo_new(1, sizeof(foo)); 
    //foo is protected from garbage collection 
    assert(X); 
    X->bar = (int*) foo_add_bar(INTEGER_VALUE(n)); 
    //Is bar protected from garbage collection? 
    assert(X->bar); 
    PROTECT(ptr_foo = R_MakeExternalPtr(X, install("extptr_foo"), R_NilValue)); 
    R_RegisterCFinalizerEx(ptr_foo, ptr_foo_finalize, 1); 
    UNPROTECT(1); 
    return (ptr_foo); 
} 

sayesinde

RT başlayanlar için

cevap

3

Bu foo nesnesinin kendi yaratımınız olduğu anlamına gelir (değil ve SEXP). Eğer öyleyse, R ile hiçbir ilgisi yoktur ve toplanan çöp DEĞİLDİR ve bu nedenle korunmaya/korunmaya gerek yoktur. Kimse ona ya da tarlalarına bakmayacak ama sen.

İçine koyduğunuz çubuk nesnesi de sizin kendi yaratımınızdır ve varsaydığım bir R nesnesini (bir SEXP) değil. Eğer bir SEXP IS veya bir SEXP içindeki verilere işaret ediyorsa, o zaman bu verilerin korunması gerekir. Daha güvenli/kolay bir yol, SEXP'deki verilerin bir kopyasını yapmak olacaktır.

ptr_foo nesnesi artık R ve çöp toplama tarafından kullanılmadığında, pt_foo_finalize işleviniz foo nesnesini (ve çubuk kısmını) kaldırmak için çağrılır.

+0

Teşekkürler Tommy. Umduğum şey buydu. Gösterdiğiniz gibi, R ve libfoo arasındaki tüm veri alışverişi, SEXP'leri içeri ve dışarı kopyalayarak gerçekleşir. Kütüphane tarafından tahsis edilen tüm nesneler bir foo_free() çağrısı ile serbest bırakılır. – user151410

1

, sen R nesneler için calloc() veya malloc() kullanmak gerekiyordu değil, "Yazma R Uzantıları" el bu konuda oldukça açıktır. İkincisi, her bir tahsis kendi KORUMA hepsini alacaktır. Üçüncüsü, dış gösterici nesneler, başka bir yerde oluşturulan bir şeyin R gösterimleridir (kanonik bir örnek için, RODBC paketine ve DB arabiriminin uygulanmasına bakın). İçinden harici işaretçi nesneleri oluşturman gerektiğini düşünmüyorum.

+0

Teşekkürler Dirk, orijinal kodumu düzenledim. Ben sadece örneği basit tutmak için calloc() kullandım. “Foo” ve “bar” ı içeren oluşturma, imha ve hesaplamalar, libfoo'daki işlevlere çağrılarak gerçekleştirilir. RODBC paketi için işaretçi için teşekkürler. – user151410

İlgili konular