Rückgabewert aus einer Windows 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
askhille
User
Beiträge: 7
Registriert: Freitag 3. März 2006, 13:34

Hallo Forum,

ich möchte in Python ein Programm schreiben, das es mir ermöglicht,
aus einer Siemens SPS Steuerung Daten auszulesen. Hierfür habe
ich von der Fa. MHJ eine DLL (ComDrvS7). Mit Visual Basic habe ich auch keine Probleme,
aber mit Python weiß ich nicht, wie ich an die Daten komme, die von der DLL zurückgegeben werden.

Hier mal mein Testprogramm:

Code: Alles auswählen

import ctypes
from ctypes import windll, c_int, c_wchar, c_char_p, byref, c_short, c_buffer, create_string_buffer

Handle = -1
ErrorString = ""
ErrorCode = c_int(-1)
Version = ""
dllfrei = 0
cpu_slot = c_int(2)  # Bei S7 - 300
error = 0
mpihandle = c_int(-1)
einleitung = 0
ipadr = ('192.168.100.205')
mpiadr = c_short(0)       # Dummy Wert da Kommunikation über TCP IP Direkt
Status = 0

# ---------------------------
mhjdll = windll.MPIA32_V40_VB
# ---------------------------

#  ************************************
#  * * * * *  MPI DLL Error   * * * * *
#  ************************************
def dll_error():

    error = mhjdll.MPI_A_GetDLLError(Handle, ErrorString, ErrorCode)
    if error == ( 0 ):
        print "DLL Fehler !"
    if error == ( 1 ):
        print "DLL O.K."
    return(error)


#   ******************************************
#   * * * * *  MPI DLL Freischalten  * * * * *
#   ******************************************
def dll_freischalten():

    KName = "--------------"
    KOrt = ----------"
    KonstStr = "MPI-DLL MHJ&Ing.-Buero Weiß"
    RegnrKundeneingabe = "-----------"
    dllfrei = mhjdll.MPI_A_MPIFreischalten(KName, KOrt, RegnrKundeneingabe, KonstStr)
    if dllfrei == ( 0 ):
        print "DLL ist nicht Freigeschaltet"
    if dllfrei == ( 1 ):
        print "Alle DLL Funktionen sind Freigeschaltet"
    return (dllfrei)


#   ***********************************************
#   * * * * *  MPI DLL TCP IP Einleitung  * * * * *
#   ***********************************************
def dll_tcp_ip_direkt():

    einleitung = mhjdll.MPI_A_Einleitung_TCP_IP_Direct(byref(mpihandle), ipadr , 2, byref(ErrorCode) )
    if einleitung == ( 0 ):
        print "Fehler Einleitung !"
    if einleitung == ( 1 ):
        print "Einleitung O.K."
    return(einleitung)

#   ************************************************************
#   * * * * *  MPI DLL Kommunikation zum AG aufbauen   * * * * *
#   ************************************************************
def dll_komm_aufbauen():

    aufbauen = mhjdll.MPI_A_KommuZumAGAufbauen(mpihandle, mpiadr, byref(ErrorCode))
    if aufbauen == ( 0 ):
        print "Keine Kommunikation mit dem AG !"
    if aufbauen == ( 1 ):
        print "Kommunikation mit dem AG aufgebaut"
    return (aufbauen)


#   ***************************************************
#   * * * * *  MPI DLL Kommunikation beenden  * * * * *
#   ***************************************************
def dll_komm_beenden():

    beenden = mhjdll.MPI_A_KommuBeenden(mpihandle, byref(ErrorCode))
    if beenden == ( 0 ):
        print "Fehler Kommunikation beenden !"
    if beenden == ( 1 ):
        print "Kommunikation beendet"
    return (beenden)


#   **********************************************
#   * * * * *  MPI DLL Read Merker Byte  * * * * *
#   **********************************************
def ReadMerkerByte():
    mb = mhjdll.MPI_A_ReadMerkerByte(mpihandle, byref(c_int(62)), 2, Status, byref(ErrorCode))
    mb_wert = Status
    print mb_wert



dll_error()
#dll_freischalten()
dll_tcp_ip_direkt()
dll_komm_aufbauen()
ReadMerkerByte()
dll_komm_beenden()
Die Funktionen dll_error(), dll_freischalten(), dll_tcp_ip_direkt(),
dll_komm_aufbauen() und dll_komm_beenden() funktionieren
Einwandfrei.

Mit der Funktion ReadmerkerByte() möchte ich z.B. ab Merker 62,
2 Bytes aus der Steuerung auslesen. Der Wert sollte in der Variable
-Status- stehen. Mir ist es bis jetzt noch nicht gelungen, diesen
Wert zu erhalten.
Wer kann mir helfen ?

MfG

Achim


,
BlackJack

Dazu müsste man wissen wie die Schnittstelle von `MPI_A_ReadMerkerByte()` aussieht. Was bedeuten die Argumente und was ist der Rückgabewert der Funktion?

``return`` ist übrigens keine Funktion, man braucht das "Argument", was ja keines ist, nicht in Klammern zu setzen. Man braucht auch keine Klammern um Zahlen bei vergleichen. Das sieht "komisch" aus.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Probier mal sowas:

Code: Alles auswählen

def read_merker_byte(pos, count):
    b = create_string_buffer(count)
    mb = mhjdll.MPI_A_ReadMerkerByte(mpihandle, byref(c_int(pos)), count, b, byref(ErrorCode))
    return b.raw

print read_merker_byte(62, 2)

oder vielleicht noch byref(b) bei der Parameterübergabe anstatt b.

Gruss
askhille
User
Beiträge: 7
Registriert: Freitag 3. März 2006, 13:34

Hallo,

Mein Programmcode sieht vielleicht etwas komisch aus, da ich blutiger
Anfänger in Python bin und von Visual Basic vielleicht ein bißchen verwöhnt bin. Dieses kleine Programm ist das Resultat etlicher Starts mit Abruch wegen Fehler etc.

Ich habe das Programm entsprechend Deinem Vorschlag abgeändert
und erhalte nun folgende Ausgabe auf der Konsole (statt print b.raw ->
print b.

DLL O.K.
Alle DLL Funktionen sind Freigeschaltet
Einleitung O.K.
Kommunikation mit dem AG aufgebaut

<ctypes.c_char_Array_2 object at 0x00C396C0>

Liegt an der Adress 0x00C396C0 nun mein Wert den ich
benötige ?? und wie bekomme ich ihn ?

Vielen Dank nochmal für die Hilfe

MFG

Achim
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Warum bleibst du nicht beim b.raw? Da käme der Wert.

Gruss
askhille
User
Beiträge: 7
Registriert: Freitag 3. März 2006, 13:34

Hallo,

da kamen zwei "Vierecke" als Ausgabe.

Darum habe print b probiert und habe die o.a. Ausgabe erhalten.

MFG


Achim
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Also wenn du repr(b.raw) machst, bekommst du die Daten zu sehen oder so wäre auch eine Möglichkeit:

Code: Alles auswählen

def read_merker_byte(pos, count):
    arr = (c_ubyte*count)([0]*count)
    mb = mhjdll.MPI_A_ReadMerkerByte(mpihandle, byref(c_int(pos)), count, arr, byref(ErrorCode))
    return list(arr)

print read_merker_byte(62, 2)
Falls du Infos über die Funktion hast, kannst du die bitte auch noch posten damit man nicht so fest rate muss ;)

Gruss
askhille
User
Beiträge: 7
Registriert: Freitag 3. März 2006, 13:34

Hallo,

hab`s gerade mit mb_wert = ord(b.raw) probiert und einen
korrekten Zahlenwert erhalten.

Deine gerade genannte Variante probiere ich auch nochmal
aus.

Vielen Dank für die schnelle Hilfe


MfG

Achim
Antworten