الوصول إلى مؤشرات باطلة في بيثون (باستخدام SWIG أو أي شيء آخر)
سؤال
لقد كنت أحاول استخدام Swig للالتفاف حول مكتبة بسيطة تستخدم IOCTL () لملء بنية مثل ما يلي:
struct data
{
header* hdr;
void* data;
size_t len;
};
بيانات هو مؤشر للمخزن المؤقت ، لين هو طول هذا المخزن المؤقت.
أنا غير قادر على معرفة كيفية التحويل بيانات إلى سلسلة بيثون (أو صفيف). علاوة على ذلك ، أحتاج إلى وسيلة لتحرير هذا المخزن المؤقت في المدمر. أي اقتراحات موضع تقدير.
المحلول
بما أنك تقول "أو أي شيء آخر" في عنوان Q - إذا اخترت استخدامها ctypes, ، يمكنك تمثيل أ void*
مع c_void_p
(واحدة من ctypes ' أنواع البيانات الأساسية, ووظائف الوصول مثل free
و memcpy
من مكتبة وقت التشغيل C (طالما أن الأخير متاح كمكتبة ديناميكية DLL /. لذا ، ولكن هذا صحيح على نطاق واسع في هذه الأيام). للحصول على مخزن مؤقت للحرف القابل للتغيير يمكنك فيه memcpy
البيانات ، الاستخدام create_string_buffer.
بالطبع يمكنك بدلاً من ذلك استخدام Python C API - pybytearray_fromstringandsize هو ما تستخدمه في هذه الحالة لعمل نسخة بايت من الخاص بك void*
وطول (وبالطبع كنت تتصل free
مباشرة ، عند الاقتضاء ، لأنه مجرد رمز C على أي حال).
إمكانية أخرى يجب مراعاتها سيثون, ، لغة تشبه Python مصممة لكتابة امتدادات Python ، بحيث يمكن لمترجم Cython إنشاء رمز C القابل للتجميع من مصادر Cython - في Cython ، الخاص بك struct
سيكون:
cdef struct data:
void* hdr
void* data
unsigned int* len
على افتراض أنك لا تريد أن تذهب إلى مشكلة الإعلان header
(أي ذلك فقط data
و len
مهم لك هنا) - size_t
, أعتقد أنه ليس جزءًا من Cython في هذا الوقت (قد أكون مخطئًا ، فإنهم يستمرون في إضافة الأشياء ؛-) ، ولكن unsigned int
ربما يمكن أن تفعل.
عذرًا ، لقد مر وقت طويل منذ أن استخدمت Swig بشكل جدي (ماذا مع كل هذه البدائل الممتازة)-كنت قد تخطيت Q لو لم يكن ذلك من أجل هذا الفقرة "أو أي شيء آخر" في العنوان ؛-).
نصائح أخرى
يوفر SWIG وحدة نمطية تسمى "CDATA.I". يجب عليك تضمين هذا في ملف تعريف الواجهة.
بمجرد تضمين هذا ، فإنه يعطي وظيفتين CDATA () و MEMMOVE (). بالنظر إلى فراغ * وطول البيانات الثنائية ، يحولها CDATA () إلى نوع سلسلة من اللغة المستهدفة. Memmove () هو العكس. بالنظر إلى نوع السلسلة ، فإنه سوف ينسخ محتويات السلسلة (بما في ذلك بايت فارغ المدمج) في نوع C void*.
يصبح التعامل مع البيانات الثنائية بسيطة مع هذه الوحدة. آمل أن يكون هذا ما تحتاجه.