Julia

2016-10-19 31 views
9

'da C void işaretleyicilerini bildirmenin uygun yolu Tamam, bu soruyu formüle etme biçimimi kötü bir şekilde mahvettim (C++ kodunu ciddi olarak yazdığımdan beri bir yıldan uzun bir süre geçti ve saf C ile oldukça sınırlı bir deneyimim var) Tekrar deneyelim.Julia

Bazı C kodu aşağıdaki

void* p; 
create_new_thing(&p); //p is now a new thing 
do_stuff_to_thing(p); //something happened to p 

Benim soru gibi bir şey yapmak bekliyoruz yazılır Julia nesneyi p oluşturmak için nasıl. Şu anda ben aynı kodu inanıyorum ama p ile p = Array(Ptr{Void}, 1) da çalışır yerine olarak ilan cevap Dahası

p = Ref{Ptr{Void}}() 
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p) 
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p) 

olduğuna inanıyoruz.

Ancak, Julia, Ref ve Ptr arasındaki tüm ayrımı çok kafa karıştırıcı buluyorum, çünkü birbirlerini izleyemediğim yollarla birbirlerinden dönüştürülüyorlar.

+0

Detay geçerli: 'void * p ile;' 'P' "yeni bir şey"(nesne) 'dir. "create_new_thing (&p);" işlevi _assign_ 'p' için bir işleve izin verir. Julia ile iyi şanslar. – chux

+0

Kelime nesnesini kullanmamamın nedeni, çok spesifik olmaktan dolayı endişelendiğimi anladım. immutable bir sayısal tip diyelim: –

+0

C, _object_ karakterleri, tamsayılar, kayan nokta, işaretçiler, diziler, yapılar, sendikalar gibi "veri depolama alanı ... içeriği değerleri gösterebilir" için _general_ terimidir ve işlevler hariç tutulabilen her şey hakkında – chux

cevap

9

Kodunuz neredeyse görünüyor. Ama dikkat et!

p = Ref{Ptr{Void}}() 
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p) 
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p) 
             # error here^

o

p = Ref{Ptr{Void}}() 
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p) 
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p[]) 
              # fixed^

p ve p[] olduğunu kullanmak nerede anlamak için en kolay yoludur yapmanın doğru yolu: Herhangi küçük bir hata, burada sahip biri gibi, bir segment hataya neden olabilir İlgili C kodunu düşünmek. C, biz

void *p; 
create_new_thing(&p) 
do_stuff_to_thing(p) 

Julia nesneleri C nesneler gibi birinci sınıf bellek adresleri yapmak gerekmez yazmak, bu yüzden bir bellek adresini almak için Julia p = Ref{Ptr{Void}}() kullanmalıdır. Bu nesne ref olarak &p C şeklinde davranır. Bu, C nesnesinin p nesnesini alması anlamına gelir, p[]'u Julia'da kullanmamız gerekir.

Yani Julia eşdeğer

p = Ref{Ptr{Void}}()     # this p corresponds to &p in C 
ccall(:create_new_thing, ..., p)  # like &p 
ccall(:do_stuff_to_thing, ..., p[]) # like *(&p); that is, like p 
+1

İlk 'ccall' imzası muhtemelen Ptr {Ptr {Void}}': http:/yerine 'Ref {Ptr {Void}} 'olmalıdır. /docs.julialang.org/en/release-0.5/manual/calling-c-and-fortran-code/#passing-pointers-for-modifying-inputs –

+1

@SimonByrne Anladığım kadarıyla, bu durumda tam olarak eşdeğerdirler, bu yüzden OP'nin kodunu korudum. –

+1

Ben şu anda eşdeğer olduklarını düşünüyorum, ancak el kitabı 'Ref' değişken işaretçiler için önerir. –