SORU
9 Kasım 2011, ÇARŞAMBA


Nasıl dinamik olarak Python türetilmiş bir tür C-API oluşturun

Türü tutorial on writing C extension modules for Python tanımlanan Noddy) vardır. Şimdi türetilmiş bir tür oluşturmak için, Noddy __new__() tek yöntem yazılmasını istiyoruz.

Şu anda aşağıdaki yaklaşım (hata denetimi okunabilir olması için elimden) kullanın:

PyTypeObject *BrownNoddyType =
    (PyTypeObject *)PyType_Type.tp_alloc(&PyType_Type, 0);
BrownNoddyType->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
BrownNoddyType->tp_name = "noddy.BrownNoddy";
BrownNoddyType->tp_doc = "BrownNoddy objects";
BrownNoddyType->tp_base = &NoddyType;
BrownNoddyType->tp_new = BrownNoddy_new;
PyType_Ready(BrownNoddyType);

Bu çalışır, ama eğer Bunu Yapmak İçin Doğru Yolu olup olmadığından emin değilim. Ben dinamik olarak öbek üzerinde türü nesne ayırma, ama bunu yaparken yorumlayıcı bir segfault yol açar, çünkü Py_TPFLAGS_HEAPTYPE bayrağı ayarla ben de bekleniyor.

Ben de açıkça type() PyObject_Call() kullanarak veya benzer aramayı düşündüm, ama fikrini bir kenara bıraktım. Bu fonksiyon Python fonksiyonu bir nesne BrownNoddy_new() kaydırmak gerekiyor ve hangi aptal gibi bu işlev, nesne, sözlük bir eşleme __new__ oluşturun.

Bu konuda gitmek için en iyi yolu nedir? Benim yaklaşımım doğru mu? Arayüz fonksiyonu özledim var mı?

Güncelleme

Python-dev e-posta listesinde ilgili bir konu(2)* *21 iki iş parçacığı vardır. İş parçacıkları ve birkaç deneyler bu tip 12 ** bir çağrı tarafından tahsis edilir sürece Py_TPFLAGS_HEAPTYPE set olmaması gerekiyor anladığım kadarıyla. İyi türünü el ile veya çağrı için type() ayrılacak olup bu ipler farklı öneriler var. tp_new yuvaya gitmek için beklenen bir C işlevi sarmak için önerilen yoldur ve ne olduğunu bilseydim, sadece ikincisi ile mutlu olurdum. Normal yöntemler için bu adım kolay PyDescr_NewMethod() uygun bir kapsayıcı nesnesini gidebilmek için çıkacak. Belgesiz işlevi PyCFunction_New() böyle bir sarıcı oluşturmak için ihtiyacım var ... belki de nesne olmasına rağmen __new__() benim yöntemi için bu tür bir kapsayıcı nesnesini oluşturmak için nasıl bilmiyorum.

CEVAP
13 Ocak 2012, Cuma


Ben bu cevap kötü ise ön özür dilerim ama PythonQt özellikle aşağıdaki dosyaları yararlı kaynaklar olabileceğini düşünüyorum: bu fikrin uygulaması bulabilirsiniz

PythonQtClassWrapper_init bu parça biraz ilginç bende de atlar:

static int PythonQtClassWrapper_init(PythonQtClassWrapper* self, PyObject* args, PyObject* kwds)
{
  // call the default type init
  if (PyType_Type.tp_init((PyObject *)self, args, kwds) < 0) {
    return -1;
  }

  // if we have no CPP class information, try our base class
  if (!self->classInfo()) {
    PyTypeObject*  superType = ((PyTypeObject *)self)->tp_base;

    if (!superType || (superType->ob_type != &PythonQtClassWrapper_Type)) {
      PyErr_Format(PyExc_TypeError, "type %s is not derived from PythonQtClassWrapper", ((PyTypeObject*)self)->tp_name);
      return -1;
    }

    // take the class info from the superType
    self->_classInfo = ((PythonQtClassWrapper*)superType)->classInfo();
  }

  return 0;
}

Bu değer belirterek bu PythonQt mu kullanmak sarıcı jeneratör değil, o yüzden tam olarak hat ile istediğin şey, ama şahsen bence çalışırken alt taban değil en iyi tasarım. Temelde, Python için birçok farklı C sarıcı jeneratör var ve insanlar iyi bir neden için bunları kullanmak - örnekleri arama sonuçları etrafında yüzen vardır ve yığın taşması üzerine belgelenmiş. Senin eline kimse görmediği bunun için bir çözüm atarlarsa, onları eğer sorun haline çalıştırırsanız, hata ayıklamak için çok daha zor olacak. Eğer kapalı kaynak varsa bile, onu korumak için var olan sonraki adam kafasını kaşıyor olacak ve karşına çıkan her yeni kişi için bunu açıklamak Zorundasınız.

Çalışan bir kod jeneratör aldıktan sonra, yapmanız gereken tüm temel C kodu korumak, ya da elle uzantısı kod güncellenmesi gerek yok. Muhtemelen çok ileri gittin cazip çözüm uzak olan)

Önerilen çözüm yeni tanıtılan PyCapsule a bit more protection yönelik olarak kullanıldıĞında) sağlayan tür güvenliği kırma bir örnektir.

Yani, bir yandan mümkün olmayabilir en uzun süreli seçimi uygulamak için türetilmiş sınıfları bu şekilde, daha ziyade wrap Kodu ve taban ne yapar en iyi ve en yeni adam var soru sadece Nokta ona belgelerine whatever solution fits best.

Bu sadece benim düşüncem. :D

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Call Me Howard

    Call Me Howa

    18 AĞUSTOS 2012
  • kindlechatmail

    kindlechatma

    25 AĞUSTOS 2010
  • njhaley

    njhaley

    24 NİSAN 2006