سؤال

لقد حصلت على وحدتي تمديد بيثون مختلفة. دعنا نسميهم A و B. الوحدة A يحتوي على نوع فئة تخزين يسمى الحاوية التي أريد استخدامها داخل الوحدة B كنوع إرجاع طريقة الفصل.

لا يمكنني العثور على أي وثائق حول كيف من المفترض أن أفعل ذلك. لقد تابعت هذه المقالة تقريبًا لإنشاء الوحدات/الفئات ، إلا أنني لم أعلن عن كل الطرق الثابتة ، بحيث يمكن الوصول إليها: http://nedbatchelder.com/text/whirlext.html

سؤالي هو إذن ، كيف يمكنني إنشاء مثيل للحاوية التي يمكنني أن أعود إليها كقيمة إرجاع pyobject* لطريقة الفصل في الوحدة B؟ يبدو تعريف الحاوية هكذا:

typedef struct {
    PyObject_HEAD

    storageclass* cnt_;
} container;

حاولت ببساطة القيام بما يلي في الطريقة المعنية ، حيث تكون Container_init هي الطريقة التي سجلتها كـ TP_INIT لفئة الحاوية:

pycnt::container* retval;
pycnt::container_init(retval, NULL, NULL);
return (PyObject*)retval;

ومع ذلك ، وفقًا لمترجم بيثون ، سأعود إلى الفصل الذي أسميته الطريقة. (أي ، myclassinstance.mymethod () يعيد myclassinstance).

من الواضح أني أسير في هذا الأمر بطريقة خاطئة ، لكن ليس لدي أي فكرة عن الطريقة الصحيحة. أي اقتراحات؟ فقط لقطع أي شخص سيقترح ذلك - لا لست مهتمًا باستخدام Swig أو Boost :: Python. لقد جربت ذلك بالفعل ولم يلعب فئة التخزين الأساسية للحاوية بشكل جيد مع أي منهما (لم يستطع Swig تحليله). حتى الآن ، لم يكن إجراء الامتدادات بنفسي غير مؤلم ، لكنني متعثر على هذا.

هل كانت مفيدة؟

المحلول

مشكلتك هي ذلك type->tp_init لا تفعل ما تريد. type->tp_init يتم استدعاؤه بعد تخصيص كائن للقيام بهذا مثيل. يجب عليك أولاً تخصيص الكائن باستخدام type->tp_new, ، ثم تمرير هذا الكائن كوسيطة أولى إلى type->tp_init. منذ أن تمرير مؤشر غير ضروري إلى tp_init, ، انتهت الرهانات. عادة لا تتصل أي من الوظائف مباشرة ، وبدلاً من ذلك اتصل بأحد PyObject_Call*() على كائن النوع نفسه لإنشاء مثيل جديد. أو توفير وظيفة C عادية لإنشاء مثيل جديد ، لوس أنجلوس PyFoo_New().

ومع ذلك ، فإن الطريقة المعتادة للقيام بالتواصل بين وحدتين تمديد هي القيام بذلك من خلال API Python. إذا كنت تريد الوحدة B لاستيراد واستخدام الوحدة A ، فأنت تتصل بها PyImport_Import() للحصول على كائن الوحدة ، PyObject_GetAttrString() للحصول على كائن النوع الذي تهتم به ، وواحد من PyObject_Call*() لإنشاء مثيل لها. في أي مكان تريد تخزين مؤشر لهذا النوع ، سوف تأخذ فقط PyObject *.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top