Probleme beim einbinden einer Labview dll

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
benny
User
Beiträge: 9
Registriert: Mittwoch 12. Dezember 2007, 16:02

Hallo Zusammen,

ich habe ein Problem mit dem einbinden einer DLL in Python. Die DLL selbst habe ich in Labview erstellt. Dabei werden jede Menge Strings (10000+) verarbeited und sollen ausgewerted an Python zurrückgegeben werden.

Dabei stürzt mir Python immer wieder ab. Vor allem wenn größere Mengen an strings verarbeited werden - kann aber auch schon vorher passieren.

Die Headerdatei sieht folgendermaßen aus:

Code: Alles auswählen

void __stdcall Jobauswahl(char SG[], char job[], char para[], char result[]);
void __stdcall Init(char APIPfad[], char Debug[]);
void __stdcall Jobabfrage(char String[], long *LNge);
void __stdcall Auswertung(char Msgs[], char Ergebnisstring[], long *LNge);
Die Python Datei:

Code: Alles auswählen

class MY_Interface():
    GLOBALS = {}
    
    # dll Initialisierung
    def __init__(self):
        print 'Init dll ...'
        self.GLOBALS['rootpath'] = os.path.dirname(__file__) + "\\"
        print os.path.dirname(__file__)
        self.GLOBALS['dllpath'] = self.GLOBALS['rootpath'] + "dll\\SharedLib.dll"
        
        # DLL laden
        try:
            self.GLOBALS['dll'] = windll.LoadLibrary(self.GLOBALS['dllpath'])
        except WindowsError:
            print 'Fehler beim laden der dll!'
            self.GLOBALS['dll'] = None
    
    # dll Schließung
    def __del__(self):
        print 'Schliesse dll ...'
                
    # api32.dll Initialisierung
    # Debug_mode - Wenn 'true' dann erscheint .txt Eingabeaufforderung
    def api_init(self, API_path, Debug_mode='false'):
        if bool(self.GLOBALS['dll']):
            self.GLOBALS['dll'].Init(API_path, Debug_mode)
    
    # Jobausführen
    # Achtung! Kein Rückgabewert
    def api_Jobauswahl(self, SG, job, para, result):
        if bool(self.GLOBALS['dll']):
            self.GLOBALS['dll'].Jobauswahl(SG, job, para, result)    
            
    # Rückgabewert von api_Jobauswahl
    def api_Jobabfrage(self):
        if bool(self.GLOBALS['dll']):
            temp = c_char_p('')
            size = c_long(100000)            
            self.GLOBALS['dll'].Jobabfrage(temp, byref(size))
            return temp.value
    
    
    def api_Auswertung(self, key):
        if bool(self.GLOBALS['dll']):
            #temp = c_char_p('')
            size = c_long(100000)        
            self.GLOBALS['dll'].Auswertung(key, temp, byref(size))
            return temp.value
Was ich nicht so richtig kapiere ist warum ich in bei der Labview dll eine size übergeben muß. Ist die wichtig?

Wär echt super wenn ihr mir einen Rat geben könntet :-)

Gruß

Benny
Zuletzt geändert von benny am Donnerstag 13. Dezember 2007, 10:38, insgesamt 1-mal geändert.
BlackJack

Woher sollen wir wissen ob die `size` wichtig ist!? Ich nehme mal an sie ist es, sonst würde es keinen Sinn machen das Argument zu übergeben.

Mindestens `api_Jobabfrage()` sollte einen ganz normalen Python-`NameError` ergeben, weil `temp` nicht definiert wurde.

Was hat es mit `GLOBALS` auf sich? Jedesmal wenn ein neues `EDIABAS_Interface`-Objekt erzeugt wird, wird der Inhalt des Dictionaries überschrieben. Warum benutzt Du nicht einfach Instanzattribute?

Ausserdem ist die "Fehlerbehandlung" etwas merkwürdig: Wenn die DLL nicht geladen werden konnte, geht's einfach weiter, nur das kein Aufruf auf dem Objekt irgendeinen Effekt hat. Ist das so gewollt?

Warum haben die Methoden den `api_*`-Präfix?

Ich würde auch mindestens die Rückgabewerte der ge"wrap"ten DLL-Funktionen bekanntgeben. Sonst passiert es am Ende noch, dass bei jedem Aufruf ein C-`int` vom Stack geholt wird. Das bedeutet auch, dass man die Funktionen aus der DLL einmal am Anfang, z.B. in der `__init__()` aus der DLL holen und an das Objekt binden sollte und das nicht bei jedem Aufruf wieder machen muss.
benny
User
Beiträge: 9
Registriert: Mittwoch 12. Dezember 2007, 16:02

Achso da hätte ich mich besser ausdrücken sollen. Wenn ich in Labview einen String zurrückgebe dann wird dieses 'size' immer mitgeliefert - ob ich es will oder nicht. Das mit dem auskommentiertem 'temp' war ein Versuch - mach es gleich Rückgängig.

Allerdings stellt die LV dll keine wrapper Funktion da. Sie benutzt zwar ne andere DLL, aber die Rückgabewerte sind komplett unabhängig davon.

Ich hab es mir so gedacht daß nur 1ne Instanz der DLL geöffnet ist. Nach der Init können dann Jobauswahl & Jobafrage bzw. Auswertung beliebig oft aufgerufen werden. Deswegen ist es mir wichtig daß ich eine Kopie des Strings als Rückgabewert erhalte, da dich die LV variable später wieder verändert.
BlackJack

Was heisst wenn Du in LabView einen String zurückgibst? Die Funktionen in der DLL haben ja scheinbar alle keinen Rückgabewert.

Kann es sein, das Du bei `Jobabfrage()` zum Beispiel als erstes Argument einen Zeiger auf einen Speicherbereich für das Ergebnis angeben musst, und als zweites einen Zeiger auf die Länge dieses Speicherbereichs und LabView kopiert dann das Ergebnis in diesen Bereich und schreibt die Länge des Ergebnisses nach `*LNge`!? Ist das bei LabView nicht dokumentiert was die Parameter bedeuten!?
Antworten