Mit pointer von ctypes Daten ausgeben.

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
funkheld
User
Beiträge: 258
Registriert: Sonntag 31. Oktober 2010, 09:26

Hallo, guten Tag.

Ich habe eine Binärdatei mit 255 Bytes.
Die möchte ich bitte einlesen als file und über einen pointer+offset den ich zu eine dll schicke auslesen.
Es funktioniert soweit aber es wird eine total anderer Integerwert ausgegeben statt ein Byte bei verschiedenen Offset..
Wenn ich bb=dl.adresse(pp,1) eingebe wird der richtige Wert ausgegeben , bei bb=dl.adresse(pp,0) kommt 65345 raus und bei
bb=dl.adresse(pp,4) kommt wieder der richtige Wert.

Liegt es hier dran :
pp=pointer(create_string_buffer(s,laenge))

Wie muss es sonst bitte heißen für eine Binärdatei ?

Danke.
Gruss


Die py-datei:

Code: Alles auswählen

import os
import struct
from ctypes import *

dl = cdll.LoadLibrary("f:/python27/pebi-py1/py.dll")

laenge=os.path.getsize("f:/python27/daten/255zufall_daten.dat")

print
print laenge," byte"
print

f = open("f:/python27/daten/255zufall_daten.dat",'rb')
s = f.read(laenge) 
    
pp=pointer(create_string_buffer(s,laenge)) 

bb=dl.adresse(pp,1) >>>>>>>>>>>>>>>>>>> 1 ist der Offset zum Pointer
print bb
Die Purebasic-Datei als Dll :

Code: Alles auswählen

ProcedureCDLL.c adresse(adr.l,stelle.l)  >>>>>>>>>>>>>>> stelle ist der Offset der übergeben wird
  wertl.c = PeekB(adr+stelle)
  ProcedureReturn wertl.c
EndProcedure
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du gibst keine Datentypen für dl.adresse an. Und darum nimmt ctypes an, das der rückgabewert immer ein integer ist, und erweitert den Wert entsprechend. Aus dem Kopf weiß ich jetzt nicht wie genau das geht, aber es ist ungefähr so :

dl.adresse.rtype = c_uchar

Das wird generell auch wichtig bei den Argumenten für DLL Funktionen. Auch die musst du setzen, sonst geht das früher oder später in die Hose.
funkheld
User
Beiträge: 258
Registriert: Sonntag 31. Oktober 2010, 09:26

Danke für die Info.

Dieses ist in der DLL ein Byte von 0-255 : wertl.c

Gruss
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das habe ich schon verstanden. Du musst als Ergebnistyp eben richtig setzen. Siehe die Dokumentation hier:

https://docs.python.org/2.7/library/cty ... turn-types
funkheld
User
Beiträge: 258
Registriert: Sonntag 31. Oktober 2010, 09:26

Danke.

Hiermit funktioniert es:

Python-Code :

Code: Alles auswählen

import os
import struct
from ctypes import *

dl = cdll.LoadLibrary("f:/python27/pebi-py1/py.dll")

laenge=os.path.getsize("f:/python27/daten/255zufall_daten.dat")

print
print laenge," byte"
print

f = open("f:/python27/daten/255zufall_daten.dat",'rb')
s = f.read(laenge)

for j in range(laenge):
	bb=c_ubyte(dl.adresse(s,j))
	print bb
Purebasic-DLL:

Code: Alles auswählen

ProcedureCDLL.c adresse(*adr,offs.l)
  wertl.c = PeekB(*adr+offs)
  ProcedureReturn wertl.c
EndProcedure
Ich übergebe zum Test meiner DLL von Purebasic die Anfangsadresse(s)und das Offset(j) und Printe dann mit Python zb den Übergabewert von der DLL:
c_ubyte(77)

Wie bekomme ich jetzt bitte aus den String "c_ubyte(77)" nur den Zahlenwert in Python um damit weiter zu machen ?

Danke.
Gruss
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das funktioniert, ist aber nicht richtig. Denn so klappt das nur, wenn dein Datentyp eine Untermenge von int darstellt. Das ist Zufällig bei dir so, muss aber nicht. Mach es wirklich so wie von mir beschrieben.

Das löst *glaube* ich auch das neue Problem. Aber 100% sicher bin ich nicht. Sonst gibt es bestimmt ein Attribut “value”.
funkheld
User
Beiträge: 258
Registriert: Sonntag 31. Oktober 2010, 09:26

Ja , mit Attribut “value” funktioniert es wunderbar.

Da es jetzt zu meiner Zufriedenheit läuft, wird auch vorläufig nichts geändert.

Danke.
Gruss
Antworten