2012-04-16 39 views
6

Vala'dan bir C makrosu kullanmaya çalışıyorum. Bana öyle görünüyor ki bu CCode direktifiyle mümkün olmalıydı ama nasıl kullanılacağı hakkında anlamlı bir belge bulamıyorum.Vala'da CCode özniteliklerini nasıl kullanırım?

"The Hacker's Guide to Vala" ve mailing list thread about calling a C macro from Vala with CCode'da CCode bağımsız değişkenleri hakkında kısa bir bölüm vardır.

Ancak kaynaklardan hiçbiri gerçekten CCode'un gerçekten ne yaptığını anlamama yardımcı oluyor. Vala'nın C kodunu nasıl oluşturduğunu açık bir şekilde etkiler, Hackers' Guide to Vala'dan CCode yönergesinin muhtemelen Valas AST'yi geçerken CCode ağacının nasıl yaratıldığına doğrudan etkisi olduğunu anlayabilirim.

CCode ne yaptığını biraz daha açıklayabilir mi?

+1

Daha fazla bilgi için: https://live.gnome.org/Vala/Manual/Attributes#CCode_Attribute –

cevap

8

Ne yazık ki, CCode hakkında tek başına mantıklı olan çok fazla belge yok. Yapmanız gereken şey, Vala ile birlikte gelen VAPI dosyalarıyla birlikte kullanılmasıdır. En temel olarak, muhtemelen bu gibi makro bir şey kullanacağız: Burada cname (yani C koduna yayılan olacaktır isim) ve cheader_filename (yani ayarlarken

[CCode(cname = "FOO", cheader_filename = "blah.h")] 
public extern void foo(); 

başlık dosyası #include d) olmalıdır. Diğer CCode özniteliklerinin çoğu, dizilerin nasıl ele alınacağını denetler. array_length = false, bir dizinin bilinmeyen uzunlukta olduğunu belirtir. Bu, bir dönüş parametresine uygulandığını belirten bir parametreye veya yönteme uygulanabilir. Örneğin: yFILE **y(void) beklenen Cı prototip ile boş sonlandırılmış bir dizi olduğu varsayılır ise, bu örnekte

[CCode(array_length = false)] public int[] x(); 
[CCode(array_null_terminated = true)] public FileStream[] y(); 
public int[] z(); 

, x, bilinmeyen bir dizi uzunluğuna sahip ve int *x(void) beklenen bir Cı prototip olacaktır. Son olarak, zlength dönen dizi.

Bunların hepsi de parametreleri uygulanabilir uzunluğunu saklamak için burada bir işaretçi, yani parametre (int *z(int *length) bir prototip, bir dizi uzunluğu üzerinden sahip olduğu varsayılmaktadır. Dizi uzunluğu varsa array_length_pos belirtmek de yararlıdır, ancak diziden hemen sonra argüman değil.P parametresi bir temsilci ise, target_pos kullanıcı verilerinin geçtiği yeri belirtir (yani, işlev işaretçisiyle birlikte gelen void*)

Ayrıca, temsilciler, sınıflar ve yapılar ile kullanmak için çeşitli CCode öznitelikleri de vardır instance_pos nerede belirtir sınıf/struct örneği veya delege kullanıcı verileri gider. Tüm konum argümanları bir kayan noktalı sayı ile belirtilir. Bu çoklu konumların kodlanmasını sağlar.

void foo(void* userdata, int length, double *dbl_array, void(*handler)(double,void*)); 

sonra bu yazabiliriz::

[CCode(cname = "foo")] 
public void foo([CCode(array_length_pos = 0.2)] double[] array, [CCode(target_pos = 0.1)] Handler func); 

Verilen Handler başka yerde bir temsilci olarak tanımlanır, sen pos değerler sonra argümanlar koymak görebilirsiniz Örneğin, bir C prototipi vardı varsayalım argüman 0 (yani, başlangıç) ve daha sonra belirli bir sırayla.

Sınıflar ve yapılar, başlatma, yıkım ve referans sayımı işlemek için işlevlere sahiptir, ancak bunlar oldukça ileri doğrudur. İşleme jenerik de biraz karmaşıktır. Yine, VAPI'ler en iyi içgörü kaynağıdır.Ancak, temel C işlevleriniz ve makrolarınız üzerinde çalışmaya başlamanız yeterlidir.

İlgili konular