استخدام أنواع python للحصول على مخزن مؤقت للعوامات من المكتبة المشتركة إلى سلسلة python
-
22-08-2019 - |
سؤال
أحاول استخدام أنواع python لاستخدام هاتين الوظيفتين C من مكتبة مشتركة:
bool decompress_rgb(unsigned char *data, long dataLen, int scale)
float* getRgbBuffer()
الوظيفة الأولى تعمل بشكل جيديمكنني معرفة ذلك عن طريق وضع بعض أكواد التصحيح في المكتبة المشتركة والتحقق من الإدخال.
المشكلة هي في إخراج البيانات.يعد المخزن المؤقت RGB مؤشرًا لتعويم (من الواضح) ويظل هذا المؤشر ثابتًا طوال عمر التطبيق.لذلك كلما أردت فك ضغط صورة ما، أقوم بالاتصال decompress_rgb
ثم تحتاج إلى رؤية ما هو موجود في الموقع المشار إليه getRgbBuffer
.أعلم أن حجم المخزن المؤقت هو (720 * 288 * sizeof(float)) لذا أعتقد أن هذا يجب أن يلعب دوره في مكان ما.
لا يوجد c_float_p
اكتب لذلك اعتقدت أنني سأجرب هذا:
getRgbBuffer.restype = c_char_p
ثم أفعل:
ptr = getRgbBuffer()
print "ptr is ", ptr
الذي يخرج فقط:
ptr = 3078746120
أعتقد أن هذا هو العنوان الفعلي وليس المحتوى، ولكن حتى لو نجحت في إلغاء الإشارة إلى المؤشر والحصول على المحتويات، فسيكون ذلك هو الحرف الأول فقط.
كيف يمكنني الحصول على محتويات المخزن المؤقت بأكمله في سلسلة بيثون؟
يحرر: كان لا بد من التغيير:
getRgbBuffer.restype = c_char_p
ل
getRgbBuffer.restype = c_void_p
ولكن بعد ذلك نجحت إجابة BastardSaint.
المحلول
لم يتم اختباره بالكامل، ولكن أعتقد أنه شيء على هذا المنوال:
buffer_size = 720 * 288 * ctypes.sizeof(ctypes.c_float)
rgb_buffer = ctypes.create_string_buffer(buffer_size)
ctypes.memmove(rgb_buffer, getRgbBuffer(), buffer_size)
المفتاح هو ctypes.memmove()
وظيفة.من وثائق ctypes:
memmove(dst, src, count)
نفس وظيفة مكتبة C memmove القياسية:نسخcount
بايت منsrc
لdst
.dst
وsrc
يجب أن تكون أعدادًا صحيحة أو مثيلات ctypes التي يمكن تحويلها إلى مؤشرات.
بعد تشغيل المقتطف أعلاه، rgb_buffer.value
سيعود المحتوى حتى الأول '\0'
.للحصول على كل البايتات كسلسلة بيثون، يمكنك تقسيم كل شيء: buffer_contents = rgb_buffer[:]
.
نصائح أخرى
لقد مر وقت طويل منذ أن استخدمت ctypes وليس لدي شيء يُرجع "*double *" سهل الاستخدام بدرجة كافية لاختبار ذلك، ولكن إذا كنت تريد c_float_p:
c_float_p = ctypes.POINTER(ctypes.c_float)
عند قراءة إجابة BastardSaint، فأنت تريد فقط البيانات الأولية، لكنني لم أكن متأكدًا مما إذا كنت تفعل ذلك كحل بديل لعدم وجود ملف c_float_p.