مشكلة تشغيل الوظائف من ملف DLL باستخدام CTTYPES في Python الموجهة للكائنات

StackOverflow https://stackoverflow.com/questions/1170372

سؤال

أنا متأكد من أن هذا لن يكون سؤالا أجاب بالفعل أو واحدة غبية. في الآونة الأخيرة لقد كنت برمجة مع العديد من الأدوات. محاولة التواصل بينهما من أجل إنشاء برنامج اختبار. ومع ذلك، فقد قمت بتوضيح بعض المشكلات بأداة واحدة محددة عند محاولة استدعاء الوظائف التي "ملثمين" خارج ملف أدوات DLL للأدوات. عندما أستخدم قذيفة بيثون التفاعلية، فإنها تعمل بشكل مثالي (على الرغم من أن الكثير من Clot Word Clobbering). ولكن عندما أقوم بتطبيق الوظائف بطريقة موجهة للكائنات، فشل البرنامج، في الواقع في الواقع لا يفشل ذلك فقط لا يفعل أي شيء. هذه هي الطريقة الأولى التي تسمى: (CTTYPES و CTYPES.UTIL مستورد)

    def init_hardware(self):
    """ Inits the instrument """
    self.write_log("Initialising the automatic tuner")
    version_string = create_string_buffer(80)
    self.error_string = create_string_buffer(80)
    self.name = "Maury MT982EU"
    self.write_log("Tuner DLL path: %s", find_library('MLibTuners'))
    self.maury = WinDLL('MlibTuners')
    self.maury.get_tuner_driver_version(version_string)
    if (version_string.value == ""):
        self.write_log("IMPORTANT: Error obtaining the driver version")
    else:
        self.write_log("Version number of the DLL: %s" % version_string.value)
    self.ThreeTypeLong = c_long * 3

الآن هذا يعمل تضخم، كل شيء مثالي وأحصل على إدخالات سجل مثالية. ولكن عندما أحاول تشغيل طريقة إضافية في البرنامج المسمى:

def add_tuner_and_controller(self, name, serial_number, tuner_number=0):
    """ Adds the tuner to the driver object, controller is inside the tuner """
    self.write_log("Adding tuner %d and the built-in controller" % tuner_number)
    TempType = self.ThreeTypeLong()
    self.maury.add_controller(c_short(tuner_number), c_char_p(self.file_path), c_char_p(name), c_int(0), c_int(0), 
                              c_long(0), c_short(serial_number), self.error_string)
    self.maury.add_tuner(c_short(tuner_number), c_char_p(name), c_short(serial_number), c_short(0),
                            c_short(1), pointer(c_double()), TempType, pointer(c_double()), pointer(c_double()),
                            pointer(c_double()), self.error_string)

يتوقف البرنامج فجأة عن العمل / الاستمرار في التشغيل، لا شيء يحدث عند استدعاء "الصورة" الذاتية ". عندما أضع كل شيء في طريقة init_hardware، فإنه يعمل بشكل مثالي، لذا أعتقد أن هناك ذاكرة طفيفة "خطأ" أو شيء ما بهيكل الهدف الموجه. أريد حقا أن أبقى بهذه الطريقة، هل هناك على أي حال لعزل الوظائف بهذه الطريقة؟ أو هل يجب علي تقييد نفسي إلى جزء كبير من التعليمات البرمجية؟


تعديل:
معلومات الوثائق:
Legend: تشير النجوم إلى المؤشرات والأقواس تشير إلى صفائف

تضيف الوظيفة Add_Tuner أو تقوم بتحديث موالف واحد في كائن برنامج تشغيل Tuner.

short add_tuner(short tuner_number, char model[ ], short serial_number, short ctlr_num, short ctlr_port, short *no_of_motors, long max_range[ ], double *fmin, double *fmax, double *fcrossover, char error_string[ ])

انتاج |: no_motors, max_range (array of three numbers), fmin, fmax, fcrossover,error_string (80+ characters long), function-return->Error flag



تضيف دالة Add_Controller أو تحديث وحدة تحكم واحدة في كائن برنامج تشغيل Tuner

short add_controller(short controller_number, char driver[ ], char model[ ], int timeout, int address, long delay_ms, char error_string[ ])

انتاج |: error_string, function-return->Error flag

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

المحلول 3

اكتشفت أن الطريقة الوحيدة لاستدعاء الوظائف في DLL المصدرة هي استخدام DLL من خلال معلمة في كل طريقة. (يقوم البرنامج بتصدير DLL وفي كل طريقة تسمى أنه سترسلها كمعلمة). يبدو قبيحا جدا ولكن هذه هي الطريقة الوحيدة التي وجدتها أن أعمل من أجلي. حاولت حتى تصدير DLL كمسمة فئة. النظام الذي أعمل معه هو كبير جدا لذا أعتقد أن هناك بعض كود بوبو في مكان ما يجعلها تفشل. شكرا لجميع ردود الفعل ونصائح!

/ Mazdak.

نصائح أخرى

لست متأكدا من مشكلتك بالضبط، لكن إليك نصائح عامة:

بالنسبة لتلك الوظائف التي تدعوها خارج المنشئ، أود أن أوصى بشدة إعداد argtypes في المنشئ كذلك. بمجرد أن أعلنت argtypes, ، يجب أن لا تحتاج إلى إلقاء جميع الحجج كما c_short, c_double, ، إلخ. علاوة على ذلك، إذا قمت بتنفيذ حجة غير صحيحة بطريق الخطأ وظيفة C، فسوف يرفع Python خطأ في وقت التشغيل بدلا من التعطل داخل DLL.

تفاصيل ثانوية أخرى، ولكن يجب أن تستخدم x = 0; byref(x) أو ربما POINTER(c_double)() بدلا من المؤشر (c_double ()) في الموالف والتحكم.

لقد كنت أكتب بعض فصول CTTYPES في بيثون 2.6 مؤخرا أيضا، وأنا لم أر أي مشاكل مثل ما تصفه. نظرا لعدم وجود أي تقارير علة Python على ذلك، أعتقد بشدة أن هناك تفاصيل دقيقة فقط أننا نتخلص في طريقتك في طريقتك.

هل هناك أي من المعلمات في وحدة تحكم إضافية أو موالف الوظيفة الإضافية فعلا القيم؟

نوصي بشدة بتحديد النماذج الأولية لوظائفك، بدلا من الاتصال بهم مباشرة مع طريات جميع المعلمات.

أنا متأكد من أنك قرأت هذه الصفحة بالفعل, ، ولكن القسم الذي تريد إلقاء نظرة عليه هو النماذج النماذج الأولية. يجعل الكود أكثر نظافة وأسهل لتتبع / تصحيح.

أيضا - كما يذكر علامة Rushakoff أيضا - استخدام المؤشر (C_Double ()) ومثل في مكالمتك أمر جميل. لدي حظي أفضل بكثير مع مؤشر ()، وتوصي مرة أخرى أنك تقوم بتقويم القيمة كمتغير، وتمرير المتغير في مكالمة عملتك. ثم على الأقل يمكنك فحص قيمتها بعد ذلك للسلوك الغريب.

تحرير: إذن سيبدو النموذج الأولي والاتصال الخاص بك شيئا مثل هذا:

prototype = WINFUNCTYPE(
    c_int,              # Return value (correct? Guess)
    c_short,            # tuner_number
    c_char_p,           # file_path
    c_char_p,           # name
    c_int,              # 0?
    c_int,              # 0?
    c_long,             # 0?
    c_short,            # serial_number
    c_char_p,           # error_string
)
# 1 input, 2 output, 4 input default to zero (I think; check doc page)
paramflags = (1, 'TunerNumber' ), (1, 'FilePath' ), (1, 'Name' ), ...
AddController = prototype(('add_controller', WinDLL.MlibTuners), paramflags)

ثم مكالمتك هي أكثر نظافة:

arg1 = 0
arg2 = 0
arg3 = 0
AddController(tuner_number, self.file_path, name, arg1, arg2, arg3, 
    serial_number, self.error_string)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top