Brauche Hilfe bei Verwendung einer DLL / Modulerstellung

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
Kornelis
User
Beiträge: 7
Registriert: Dienstag 8. April 2008, 06:54

Mittwoch 16. Juli 2008, 11:24

Hallo Zusammen,

ich habe ein kleines monochromes grafikfähiges LCD, welches per USB an den Rechner angeschlossen wird. Zu diesem Display gibt es eine DLL über die Display angesprochen werden kann. Die Funktionen der DLL sind in einem PDF Dokument beschrieben. In anderen Programmiersprachen habe ich schon einige Programme dafür geschrieben, und jetzt würde ich es gerne in Python probieren (zu Übungszwecken).

Ich habe es soweit auch schon geschaft, dass Display von Python aus anzusprechen, doch leider weiß ich bei einigen Funktionen nicht so ganz, wie ich damit umgehen soll. Speziell geht es da um die Übergabe eines Pointers auf ein Charakter Array. Um es zu konkretisieren habe ich probleme mit der Funktion setBitamp.

Das ist der Code den ich soweit schon entwickelt habe, mit dem ich das Display auch ansprechen kann bzw. ein paar Funktion auf dem Display und der DLL schon ausführen kann:

Code: Alles auswählen

from ctypes import WinDLL, byref,c_int,c_char

class LcdHandler(object):
    
    def __init__(self,devNum):
        self.__lcd = WinDLL("luise.dll")
        self.__devNum = devNum
    
    # convert the returncode into an string
    def _checkReturnCode(self,rc):
        
        if (rc == 0):
            return "ok"
        elif (rc == 1):
            return "can't open USB-Device"
        elif (rc == 2):
            return "USB write error"
        elif (rc == 3):
            return "USB read error"
        elif (rc == 4):
            return "file doesn't exist"
        elif (rc == 5):
            return "faulty file"
        elif (rc == 5):
            return "out of range"
        else:
            return "Unknown Display RC"   
    
    # Get Version of the used luise.dll    
    def getDll(self):
        return self.__lcd.GetDllVersion()
    
    # Open LCD Device    
    def openDevice(self):
        return self._checkReturnCode(self.__lcd.LUI_OpenDevice(self.__devNum))
    
    # Close LCD Device
    def closeDevice(self):
        return _checkReturnCode(self.__lcd.LUI_CloseDevice(self.__devNum))
    
    # Configure LCD Mode
    def lcdMode(self,gfxMode=0,gfxInvert=0,screenRotation=0,ioRefresh=2):
        return _checkReturnCode(self.__lcd.LUI_LCDmode(self.__devNum,gfxMode,gfxInvert,screenRotation,ioRefresh))
    
    # Set Text on LCD
    def setText(self,screenPosX,screenPosY,textFieldWidth,textFieldHight,transparency,fontFileName,fontWidthSpace,fontHightSpace,textdata):
        return _checkReturnCode(self.__lcd.LUI_Text(self.__devNum,screenPosX,screenPosY,textFieldWidth,textFieldHight,transparency,fontFileName,fontWidthSpace,fontHightSpace,textdata))
    
    # TODO: Check how to handle pointer to charater array in python
    
    # Load Bitmap
    def setBitmap(self,screenNr,screenPosX,screenPosY,bmpOffsetX,bmpOffsetY,bmpWidth,bmpHight,bmpDataWidth,bmpDataHight,bmpData):
        return _checkReturnCode(self.__lcd.LUI_Bitmap(self.__devNum,screenNr,screenPosX,screenPosY,bmpOffsetX,bmpOffsetY,bmpWidth,bmpHight,bmpDataWidth,bmpDataHight,bmpData))
    
    # Load Bitmap from File
    def setBitmapFile(self,screenNr,screenPosX,screenPosY,bmpOffsetX,bmpOffsetY,bmpWidth,bmpHight,bmpFile):
        return _checkReturnCode(self.__lcd.LUI_BMPfile(self.__devNum,screenNr,screenPosX,screenPosY,bmpOffsetX,bmpOffsetY,bmpWidth,bmpHight,bmpFile))
    
    # Set the state of a single Pixel
    def setPixel(self,screenNr,screenPosX,screenPoxY,state):
        return _checkReturnCode(self.__lcd.LUI_SetPixel(self.__devNum,screenNr,screenPosX,screenPoxY,state))
    
    # Get the state of a single Pixel
    def getPixel(self,screenNr,screenPosX,screenPoxY,state):
        state = c_char()
        return _checkReturnCode(self.__lcd.LUI_GetPixel(self.__devNum,screenNr,screenPosX,screenPoxY,byref(state))), ord(state.value)
    
    # Turn Display on or off
    def displayOnOff(self,value):
        return _checkReturnCode(self.__lcd.LUI_DispOnOff(self.__devNum,value))
    
    # Turn Displaylight on or off
    def ccflOnOff(self,value):
        return _checkReturnCode(self.__lcd.LUI_CCFL(self.__devNum,value))
    
    # Get the Contrast Value of the Display
    def getContrast(self):
        contrast = c_char()
        return _checkReturnCode(self.__lcd.LUI_GetContrast(self.__devNum,byref(contrast))), ord(contrast.value)
    
    # Set the Contrast Value of the Display
    def setContrast(self,value):
        return _checkReturnCode(self.__lcd.LUI_SetContrast(self.__devNum,value))
        
    # Get the Data of the Input Ports (LUI v1 only)
    def getInport(self):
        portData = c_char()
        return _checkReturnCode(self.__lcd.LUI_InPort(self.__devNum,byref(portData))), ord(portData)
    
    # Set the Data of the Output Ports
    def setOutport(self,portData):
        return _checkReturnCode(self.__lcd.LUI_OutPort(self.__devNum,portData))
    
    # Get the Serial of the Display Device
    def getSerial(self):
        serial = c_int()
        return _checkReturnCode(self.__lcd.LUI_GetSerial(self.__devNum,byref(serial))), serial
    
    # Set the Screen Refresh Control
    def setScreenRefresh(self,gfxScreen0,gfxScreen1,txtScreen):
        return _checkReturnCode(self.__lcd.LUI_ScreenRefreshControl(self.__devNum,gfxScreen0,gfxScreen1,txtScreen))
    
    # Get the state of the TouchScreen
    def getTS(self):
        tsDataType = c_int * 3
        tsData = tsDataType()
        return _checkReturnCode(self.__lcd.LUI_TouchScreen(self.__devNum,byref(tsData))), tsData
Die API zu dem Display gibts hier


Ich hoffe ihr könnt mir ein paar Tips geben.

Danke & Gruß

Kornelis

EDIT by Gerold: Code-Tag geändert
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Mittwoch 16. Juli 2008, 12:01

Kornelis hat geschrieben:

Code: Alles auswählen

class LcdHandler(object):
    
    # convert the returncode into an string
    def _checkReturnCode(self,rc):
        
        if (rc == 0):
            return "ok"
        elif (rc == 1):
            return "can't open USB-Device"
        elif (rc == 2):
            return "USB write error"
        elif (rc == 3):
            return "USB read error"
        elif (rc == 4):
            return "file doesn't exist"
        elif (rc == 5):
            return "faulty file"
        elif (rc == 5):
            return "out of range"
        else:
            return "Unknown Display RC"   
    
    # Open LCD Device    
    def openDevice(self):
        return self._checkReturnCode(self.__lcd.LUI_OpenDevice(self.__devNum))
    
    # Close LCD Device
    def closeDevice(self):
        return _checkReturnCode(self.__lcd.LUI_CloseDevice(self.__devNum))
    
Wie kann denn das Funktionieren?
Der name _checkReturnCode ist nicht definiert, bei mir gibt sowas nen NameError:

Code: Alles auswählen

class Foo(object):
    def foo(self):
        return "foo"

    def bar(self):
        return foo()
btw, _checkReturnCode würde ich als normale Funktion definieren, z.B. so:

Code: Alles auswählen

def _checkReturnCode(rc):
    return {
        0 : "ok",
        1 : "can't open USB-Device",
        2 : "USB write error",
        3 : "USB read error",
        4 : "file doesn't exist",
        5 : "faulty file",
        5 : "out of range",
    }.get(rc, "Unknown Display RC")
Und warum ist lcd privat? Das ist nur dafür gedacht, dass das Attribut in einer Unterklasse nicht ausversehen(!) überschrieben wird, für nix anders.
Alles andere ist mit einem Unterstrich gut bedient.
Kornelis
User
Beiträge: 7
Registriert: Dienstag 8. April 2008, 06:54

Mittwoch 16. Juli 2008, 12:19

audax hat geschrieben:
Wie kann denn das Funktionieren?
Der name _checkReturnCode ist nicht definiert, bei mir gibt sowas nen NameError:
Jep du hast recht. Ich gebe zu, ich habe es noch nicht über das Modul probiert. Meine Versuche das Display anzusprechen habe ich direkt über die Shell mit den einzelnen Commands gemacht...
Ich muss einfach noch das self immer setzten, wenn ich es wirklich innerhalb der Klasse haben will.
audax hat geschrieben: btw, _checkReturnCode würde ich als normale Funktion definieren
Nur für mein allgemeines Python Verständnis, welchen Vorteile bringt mir das? (Ich beschäftige mich noch nicht sooo lange / oft mit der Sprache)
audax hat geschrieben: Und warum ist lcd privat? Das ist nur dafür gedacht, dass das Attribut in einer Unterklasse nicht ausversehen(!) überschrieben wird, für nix anders.
Alles andere ist mit einem Unterstrich gut bedient.
Und es dient dazu, dass die Variable nicht direkt von außen angesprochen werden kann. Sobald ich eine Instanz der Klasse habe, könnte ich ja direkt die Variable lcd ansprechen ohne über irgendwelche Methoden zu gehen.

Soweit schon mal danke für deine Tips.

Haste du noch vorschläge, wie ich das mit dem Character Array in dem die Bitmap Daten stehen am besten realisieren kann?

Danke & Gruß

Kornelis
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Mittwoch 16. Juli 2008, 12:28

Schau Dir mal http://www.python-forum.de/topic-14459.html an. Hier solltest Du reichlich Tips zum Umgang mit verschiedensten Typen in ctypes finden.
MfG
HWK
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Mittwoch 16. Juli 2008, 12:43

Kornelis hat geschrieben:
audax hat geschrieben: btw, _checkReturnCode würde ich als normale Funktion definieren
Nur für mein allgemeines Python Verständnis, welchen Vorteile bringt mir das? (Ich beschäftige mich noch nicht sooo lange / oft mit der Sprache)
_checkReturnCode greift auf nichts Klasseninternes zu, deshalb hat es in der Klasse nichts zu suchen. In Methoden gehört nur Verhalten, was direkt mit dem Objekt zu tun hat, nichts anderes. Sonst wirds schnell unübersichtlich.
audax hat geschrieben: Und warum ist lcd privat? Das ist nur dafür gedacht, dass das Attribut in einer Unterklasse nicht ausversehen(!) überschrieben wird, für nix anders.
Alles andere ist mit einem Unterstrich gut bedient.
Und es dient dazu, dass die Variable nicht direkt von außen angesprochen werden kann. Sobald ich eine Instanz der Klasse habe, könnte ich ja direkt die Variable lcd ansprechen ohne über irgendwelche Methoden zu gehen.
Das kann man mit __lcd auch, und zwar mit foo.__Klassenname__lcd. Es gibt keine Art in Python Variablen vor Zugriff von außen zu verbergen. Per Konvention werden Namen die zur Implementation und nicht zu API gehören mit einem Unterstrich versehen, das muss auch reichen. Das geht alles nur(!) über Konvention. Wenn sich dann trotzdem jemand ins Knie schießen will und auf deine internen Variablen zugreift ist er eben selbst schuld wenn sich daran was ändert.
Siehe dazu auch das offizielle Tutorial auf python.org
Haste du noch vorschläge, wie ich das mit dem Character Array in dem die Bitmap Daten stehen am besten realisieren kann?
Ach..mit ctypes hab ich mich noch net beschäftigt, ich würd für sowas wohl eher Pyrex oder Cython nehmen.
Antworten