Seite 2 von 2
Re: C-Code nach Python portieren
Verfasst: Dienstag 15. März 2011, 10:14
von deets
Der erste ist genau wie erwartet.
Das zweite sieht mir noch nicht mal nach gueltigem python aus?!? cast ist eine *Funktion* in Python, kein Operator wie in C. Hast du das mal versucht?
Re: C-Code nach Python portieren
Verfasst: Dienstag 15. März 2011, 10:22
von deets
Ok, jetzt habe ich deinen Post erst richtig verstanden. Offensichtlich ist POINTER(foo) ein callable.
Wie dem auch sei, du musst die Funktion cast benutzen, sowas wie
cast(wert, POINTER(typ))
Kann auch sein, dass die Argumente umgedreht sind, bitte mal die Doku checken.
Re: C-Code nach Python portieren
Verfasst: Dienstag 15. März 2011, 10:27
von Torsten2000
Wie caste ich denn auf POINTER(c_byte)?
ich hatte das jetzt mal so probiert... ist sehr wahrscheinlich totaler quatsch
POINTER(c_byte)( )
ich habe folgende typen gefunden
c_char_p char * (NUL terminated) string or None
c_wchar_p wchar_t * (NUL terminated) unicode or None
c_void_p void * int/long or None
c_byte_p ist leider nicht dabei...
casten auf c_char_p, c_wchar_p und c_void_p hat leider kein erfolg gebracht

Re: C-Code nach Python portieren
Verfasst: Dienstag 15. März 2011, 11:25
von BlackJack
@Torsten2000: Der allererste Aufruf den Du gezeigt hast, der sollte so auch funktionieren. `ctypes` nimmt es an der Stelle ähnlich "ungenau" wie C und übergibt bei einem Array nicht das Array selbst, sondern einen Pointer darauf. Das passt schon.
Kann es sein, dass die Signatur einfach nicht stimmt und die Funktion in der DLL andere/weniger Argumente entgegen nimmt?
Oh und natürlich das Offensichtliche: Ist das überhaupt eine DLL, die die Windows-Aufrufkonvention verwendet? Kann es sein, dass Du die nicht als windll sondern als cdll laden musst!?
Re: C-Code nach Python portieren
Verfasst: Dienstag 15. März 2011, 13:39
von Torsten2000
Vielen Dank, dass ihr euch so viel Zeit für mich nehmt...
Also im Beispielprogramm steht der Aufruf so:
Code: Alles auswählen
unmangle(m_lpbWave, m_iCurSize, 0, m_TestBuf, sizeof(m_TestBuf), ghmTbl[giHwMode].iP1, ghmTbl[giHwMode].iP2, ghmTbl[giHwMode].iP3);
also nehme ich an, das die Anzahl der Argumente passt.
Die DLL habe ich von dem gleichen Hersteller. Daher war ich davon ausgegangen, dass das auch eine WinDLL ist.
Ich habe aber mal beim laden auch CDLL ausprobiert.
Code: Alles auswählen
#LAWaveExt_dll = windll.LoadLibrary("LAWaveExt")
LAWaveExt_dll = cdll.LoadLibrary("LAWaveExt")
Was leider kein Unterschied von der Fehlermeldung gemacht hat.
_unmangle( Wave, len(Wave), Channel, Wave_of_channel, len(Wave_of_channel), P1, P2, P3)
ArgumentError: argument 1: <type 'exceptions.TypeError'>: expected LP_c_byte instance instead of str
Re: C-Code nach Python portieren
Verfasst: Dienstag 15. März 2011, 13:43
von Torsten2000
vielleicht ist das noch hilfreich.
in der lawaveext.h steht
Code: Alles auswählen
extern "C" int __declspec(dllexport) unmangle(BYTE *lpbWave, int sizeofWave, int iChan, BYTE* lpChan, int sizeofChan, int ip1, int ip2, int ip3);
Re: C-Code nach Python portieren
Verfasst: Dienstag 15. März 2011, 14:09
von deets
BlackJack hat geschrieben:@Torsten2000: Der allererste Aufruf den Du gezeigt hast, der sollte so auch funktionieren. `ctypes` nimmt es an der Stelle ähnlich "ungenau" wie C und übergibt bei einem Array nicht das Array selbst, sondern einen Pointer darauf. Das passt schon.
Haette ich das mal frueher gewusst... ich hab' immer schoen brav gepointert, und *dann* noch casten muessen.
You live, you learn.
Re: C-Code nach Python portieren
Verfasst: Dienstag 15. März 2011, 14:36
von deets
Torsten2000 hat geschrieben:
_unmangle( Wave, len(Wave), Channel, Wave_of_channel, len(Wave_of_channel), P1, P2, P3)
ArgumentError: argument 1: <type 'exceptions.TypeError'>: expected LP_c_byte instance instead of str
Aber das ist doch ein komplett anderer Fehler - das sieht so aus, als ob du keinen Array-Pointer uebergibst, sondern einen Python-string.
Re: C-Code nach Python portieren
Verfasst: Dienstag 22. März 2011, 16:14
von Torsten2000
Oh je...
ich habe wieder ein Problem bekommen...
und zwar funktionierte das messen schon recht gut.
Ich muss jetzt allerding ein Gerät ansteuern, was nur mit IronPython geht.
Blöderweise bringt der mir eine Fehlermeldung in IronPython
in start_capturing _ctypes.ArgumentError: expected c_long, got c_long_Array_16
Damit funktioniert das Messen mit dem Logikanalysator nicht mehr!!!
Zur Erinnerung:
Code: Alles auswählen
TriggerContinue = (c_int * 16)()
TriggerData = (c_byte * (16 * 64))()
_capture = larun_dll.ulaCapture
_capture.argtypes = [POINTER(Trigger), POINTER(c_int), POINTER(c_byte)]
_capture.restype = c_bool
Code: Alles auswählen
def start_capturing():
return _capture(trigger, TriggerContinue, TriggerData)
Was mache ich denn jetzt?
Wie löst man das Problem am besten?
Vielen Dank für eure Hilfe!
Grüße Torsten
Re: C-Code nach Python portieren
Verfasst: Dienstag 22. März 2011, 16:56
von BlackJack
Hilft folgende Änderung? (`byref()` ist aus `ctypes`)
Code: Alles auswählen
def start_capturing():
return _capture(trigger, byref(TriggerContinue), byref(TriggerData))
Re: C-Code nach Python portieren
Verfasst: Dienstag 22. März 2011, 17:02
von Torsten2000
Hallo BlackJack,
vielen Dank nochmal für eine schnelle Antwort!
leider hat das nicht geholfen.
Fehlermeldung:
in start_capturin _ctypes.ArgumentError: expected LP_c_long, got NativeArgument
Viele Grüße
Torsten
Re: C-Code nach Python portieren
Verfasst: Mittwoch 30. März 2011, 12:22
von Torsten2000
Mmmm.... hat noch jemand eine Idee, woran das liegen könnte, dass ich in IronPython den Logikanalysator nicht ansteuern kann? schon doof, das das nicht abwärtskompatibel ist...
Ich könnte evt. ein Umweg machen: aus dem Python-Skript ein IronSkrift über die Shell aufrufen... aber das ist wahrscheinlich sehr langsam und nicht sehr elegant...
Danke für eure Hilfe
Grüße
Torsten
Re: C-Code nach Python portieren
Verfasst: Mittwoch 6. April 2011, 12:28
von Torsten2000
Hallo,
ich habe nochmal die ctypes-Anleitung durchgearbeitet und habe leider immer noch das Problem, dass in IronPython die Fehlermeldung kommt (in Python funktioniert es).
in start_capturing _ctypes.ArgumentError: expected c_long, got c_long_Array_16
ich verstehe das nicht wirklich und bräuchte da dringend Hilfe (Die Abgabe von der Diplomarbeit kommt immer nächer).
Danke schon mal für eure Hilfe.
Grüße
Torsten
Re: C-Code nach Python portieren
Verfasst: Mittwoch 6. April 2011, 12:38
von deets
Die Fehlermeldung ist doch recht klar. Und ich habe dir auch schon vor Wochen genau dazu was bezueglich casting gesagt.
Re: C-Code nach Python portieren
Verfasst: Mittwoch 6. April 2011, 12:45
von BlackJack
@Torsten2000: Ansonsten ist das Thema IronPython's `ctypes`-Implementierung und Abweichungen von CPython's `ctype` hier vielleicht etwas zu speziell. Schau mal ob es für beides nicht auch Mailinglisten gibt, wo die Entwickler mitlesen oder zumindest Leute die auch die Implementierung kennen.
Re: C-Code nach Python portieren
Verfasst: Mittwoch 6. April 2011, 14:28
von Torsten2000
Hallo BlackJach,
danke für deine Antwort.
Ich rufe jetzt mit
ein externes IronPython-Script auf.
es funktioniert zwar aber ist sehr langsam, da er sich immer wieder neu verbinden muss.
man man zwei Python-Scripte gleichzeitig laufen lassen, die sich Variablen teilen?
Damit könnte man evtl. das auch beschleunigen
Re: C-Code nach Python portieren
Verfasst: Montag 18. April 2011, 17:05
von Torsten2000
Sagt mal ....
was mir gerade aufgefallen ist...
Meine Read-Funktion ist der totaler blödsinn oder?
Code: Alles auswählen
def read_data_from_file(filename):
import os
global Wave
f=open(filename, 'rb')
print os.path.getsize(filename)
Wave = (c_byte * ( os.path.getsize(filename) ))()
print 'Lese Daten von der Datei "' + filename + '" ...',
Wave = f.read()
f.close
print ' OK'
print
Das ist ja dann nicht in das Byte-Array reingeschrieben...
Der erstellt mir ja eine neue Variable.
muss ich da auch mit dem strukt paket arbeiten?
oder wie machte ich das?
Re: C-Code nach Python portieren
Verfasst: Montag 18. April 2011, 17:15
von Torsten2000
Nochmal auf das Problem zurück zu kommen...
Zur Erinnerung:
Also - in der DLL ist eine Funktion
Code: Alles auswählen
unmangle(BYTE *lpbWave, int sizeofWave, int iChan, BYTE* lpChan, int sizeofChan, int ip1, int ip2, int ip3)
und so habe ich das eingebunden
Code: Alles auswählen
import ctypes
LAWaveExt_dll = windll.LoadLibrary("LAWaveExt")
_unmangle = LAWaveExt_dll.unmangle
_unmangle.argtypes = [POINTER(c_byte), c_int, c_int, POINTER(c_byte), c_int, c_int, c_int, c_int]
_unmangle.restype = c_int
def unmangle():
Channel = 0
Wave = (c_byte * ( 80 ))()
Wave_of_channel = (c_byte * ( 80 ))()
_unmangle( Wave, sizeof(Wave), Channel, Wave_of_channel, sizeof(Wave_of_channel), P1, P2, P3)
Da bringt er folgende Fehlermeldung:
_unmangle( Wave, sizeof(Wave), Channel, Wave_of_channel, sizeof(Wave_of_channel), P1, P2, P3)
ValueError: Procedure probably called with too many arguments (32 bytes in excess)
Muss ich bei der Übergabe von den Parameter die "pack"-Funktion aus Struct benutzen oder macht der das automatisch...
weil ich bei der Deklaration ja die Größe angegeben haben...
Viele Grüße
Torsten
Re: C-Code nach Python portieren
Verfasst: Montag 18. April 2011, 18:06
von BlackJack
@Torsten2000: Du hast da doch gar kein ``struct``/`ctypes.Structure`.