Frage

Ich hoffe, dass dies nicht eine bereits beantworteten Frage oder ein dummer sein. Vor kurzem habe ich mit mehreren Instrumenten worden Programmierung. Der Versuch, zwischen ihnen zu kommunizieren, um ein Testprogramm zu erzeugen. Allerdings habe ich einige Probleme mit einem bestimmten Instrument encoutered wenn ich versuche, Funktionen aufzurufen, die ich „maskiert“ aus der Instrumente DLL-Datei haben. Wenn ich die interaktive Python-Shell verwenden, es funktioniert perfekt (obwohl seine Menge Wort Verfälschungs). Aber wenn ich die Funktionen in einer objektorientierten Weise implementieren das Programm fehlschlägt, und tatsächlich ist es nicht scheitert es funktioniert einfach nichts tun. Dies ist die erste Methode, die aufgerufen wird: (ctypes und ctypes.util importiert)

    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

Nun, da Arbeiten quellen, ist alles perfekt und ich perfekt Log-Einträge. Aber wenn ich versuche, ein Verfahren weiter in das Programm auszuführen genannt:

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)

Das Programm plötzlich nicht mehr funktioniert / läuft weiter, happenes nichts, wenn die „self.maury“ -Linie genannt wird. Wenn ich alles in der init_hardware Methode platzieren funktioniert es perfekt, so vermute ich, ein leichter Speicher „Fehler“ es gibt oder etwas mit dem Ziel orientierte Struktur. Ich will es wirklich so bleibt, ist es trotzdem die Funktionen auf diese Weise zu isolieren? oder muss ich mich auf einen großen Teil des Codes beschränken?


EDIT:
Dokumentation info :
[Legende: Die Sterne zeigen Zeiger und die Klammern Arrays]

Die add_tuner Funktion hinzufügt oder Updates ein Tuner im Tunertreiberobjekt.

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[ ])

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



Die add_controller Funktion hinzufügt oder Updates einen Controller in der Tuner-Treiber Objekt

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

Output : error_string, function-return->Error flag

War es hilfreich?

Lösung 3

Ich fand heraus, dass der einzige Weg, um die Funktionen in der exportierten DLL rufen Sie die DLL durch einen Parameter in jedem Verfahren zu verwenden war. (Das Programm exportiert die dll und in jeder aufgerufenen Methode wird es als Parameter senden). Es sieht ziemlich hässlich, aber das ist der einzige Weg, die ich für mich zu arbeiten, gefunden. Ich habe sogar versucht, die DLL als Klassenattribut zu exportieren. Das System, das ich mit gerade arbeite ist ziemlich heftige also denke ich, gibt es einige boboo-Code irgendwo, dass es nicht macht. Vielen Dank für das Feedback und Tipps!

/ Mazdak

Andere Tipps

Ich bin mir nicht sicher über Ihr genaues Problem, aber hier ein paar allgemeine Tipps:

Für die Funktionen, die Sie außerhalb des Konstrukteurs anrufen, würde ich empfehlen, ihre argtypes in der auch Konstruktor. Sobald Sie die argtypes erklärt haben, sollten Sie nicht alle Argumente als c_short, c_double usw. Außerdem werfen müssen, wenn Sie versehentlich ein falsches Argument an eine C-Funktion übergeben kann, wird Python einen Laufzeitfehler erhöhen statt Absturz innerhalb die DLL.

Ein weiteres kleines Detail, aber Sie sollten x = 0; byref(x) oder vielleicht POINTER (c_double)() statt Zeiger (c_double ()) in der Tuner- und Controller.

Ich habe auch einige ctypes Klassen in Python zu schreiben 2.6 vor kurzem, und ich habe keine Probleme gesehen wie das, was Sie beschreiben. Da es offenbar kein Python Bug-Report auf, dass entweder, ich glaube fest daran, dass es nur eine Minute Detail, dass wir beide mit Blick in Ihrer Methode sind, dass ein Problem aufgetreten ist.

Sind alle Parameter in Add-Controller oder Add-Tuner tatsächlich Werte zurückgeben?

Dringend empfohlen, dass Sie Prototypen Ihrer Funktionen definieren, anstatt sie mit Abgüsse aller Parameter direkt aufrufen.

ich bin sicher, Sie haben diese Seite bereits lesen, aber der Abschnitt Sie wollen sehen Funktionsprototypen ist. Macht den Code viel sauberer und einfacher zu verfolgen / debug.

Auch - wie Mark Rushakoff auch erwähnt - mit Zeiger (c_double ()) und wie in Ihrem Anruf ist ziemlich eklig. Ich habe viel mehr Glück w / POINTER () und empfehlen nochmals, dass Sie den Wert als Variable predeclare, und die Variable in Ihrer Funktionsaufruf übergeben. Dann zumindest kann man seinen Wert später für seltsames Verhalten untersuchen.

EDIT: Also Ihr Prototyp und Call etwas wie folgt aussehen:

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)

Dann wird Ihr Anruf ist viel sauberer:

arg1 = 0
arg2 = 0
arg3 = 0
AddController(tuner_number, self.file_path, name, arg1, arg2, arg3, 
    serial_number, self.error_string)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top