Seite 3 von 5
Re: Delphi DLL
Verfasst: 30.11.2010 15:20
von ts-soft
Galahat hat geschrieben:Ich schmeiß das ding gleich vorm Schneepflug
Naja, Delphi und VB DLLs haben so Ihre Tücken
Code: Alles auswählen
Prototype USB32IO_OpenDevice(*Par1, *Par2, *Par3, *Par4)
Define.l DevNum
als ersten Parameter übergeben
Musste einfach mal probieren

Re: Delphi DLL
Verfasst: 30.11.2010 15:44
von D.J.Peters
Also ich habe mir die VB und Delphi Deklarationen angesehen
und als alter Hase muss ich mich doch wundern.
Soweit ich es sehe gibt es die DLL im Treiber/XP Verzeichnis
das merkwürdige ist das nicht nur VB und Delphi die selbe DLL benutzen
sondern exakt die selben exportierten Funktionen.
z.B. OpenDevice()
Demnach würde bei VB String der BSTR Datentype verwendet und bei Delphi der DELPHISTRING Datantype.
Was eigentlich so nicht sein kann weil der BSTR vom DELPHISTRING abweicht.
Aber aufgepast da in VB der String BYVAL übergeben wird und nicht BYREF
wird die Addresse des ersten Zeichens übergeben
(das ist nichts anderes als ein *pointer kann daher sogar in PB als long deklariert werden string.l)
Delphi erkennt vermutlich an der DLL/STDCALL Deklaration das ebenfals "nur" ein Zeiger auf das erste Zeichen erwartet wird.
Also übergebe die Addresse des ersten Zeichen es muss nur sichergestellt sein das
das letze Zeichem im String immer eine 0 ist sonst kann die DLL die Länge des Stringes nicht ermitteln.
Grüsse Joshy
Re: Delphi DLL
Verfasst: 30.11.2010 15:49
von Galahat
Jetzt schmiert er nicht mehr ab...
Jetzt muss ich erst mal begreifen, was sonst noch nicht ganz stimmt.
mit @Devnum , was eine Art Geräte-ID ist (eigentlich 1 Byte groß), bekomme ich von GetErrorDevice ein 2 zurück, was darauf hindeutet, das der Inhalt wohl >31 ist....kein wunder, wenn er einen Zeiger bekommt
Re: Delphi DLL
Verfasst: 30.11.2010 15:56
von Galahat
@Joshi
Wo lernt man denn sowas ???
Demnach lag ich ja ganz am Anfang mit OPENDEVICE(..., Par1.p-bstr, ...,...) garnicht mal so daneben, oder verstehe ich dich da falsch?
Re: Delphi DLL
Verfasst: 30.11.2010 20:22
von Galahat
Mir ist da was unter die Augen gekommen
Etwas weiter oben erläutert D.J.Peters etwas ganz interassantes. Klingt plausibel, doch das das mit schnoden VB-Strings wohl auch klappt, liegt unter anderem vielleicht auch an der Tatsache, das ein VB-String 1Byte pro Zeichen + 10Byte groß ist, wie ich gerade in meinem alten VB Buch lesen konnte.
Darauf habe ich den ganzen Pointerverwurschtelkram herausgenommen und schlicht Fixed Strings definiert.
Mit gewissem Erfolg. Denn zuvor mochte er nicht mit .s im Prototypen arbeiten...das gab immer heftige Probleme.
Ich frage mich nur, wenn ich einen String bauen möchte mit dem Inhalt EZUSB + NULL + 10Byte, wie baue ich denn das zusammen ??

Re: Delphi DLL
Verfasst: 30.11.2010 21:53
von D.J.Peters
Hallo Galahat,
Du kannst meiner kleiner Ausführung ruhig vertrauen.
Wenn in VB:
A$=B$+C$
benutzt wird dan werden wirklich OLE Strings benutzt der heute sogennante BSTR String Datentype.
Da alle WINDOWS OS DLL's in C geschrieben sind z.B. KERNEL32, GDI32, USER32
benutzen alle nicht UNICODE Routienen den C String Datenentype "char *".
Würde man nun mit VB eine OS Funktion aufrufen die einen String füllt und es würde der BSTR
als Parameter übergeben dann würde der BSTR - Descriptor mit den Zeichen überschrieben
und ein "print Param$" würde zwangsläufig zum Segfault Error führen.
Daher deklariert man ihn als CallMe(BYVAL Param as string, BYVAL WieGrossIstDerString as integer)
Nun geht VB hin und läst sich vom BSTR die Addresse geben welche auf das erste Zeichen zeigt
und ruft CallMe() damit auf.
Beispiel:
Dim Param as string
Param="Test"
CallMe(Param,len(Param))
Schön daran zu sehen ist das der BSTR keine 0 als Endterminator benutzt und daher mit LEN() die Länge ermittelt werden muss.
Zurück zu deiner USB DLL:
OpenDevice()
Will nun z.B. den Gerätenamen als String-Addresse haben
aber ohne das Du die länge des Stringes als zusätzlichen Parameter mit angeben must.
Ergo:
Benötigt der string eine 0 als Endemakierung (Terminator)
String = "Hello world" + chr(0)
Schönen Abend noch.
Grüsse Joshy
Re: Delphi DLL
Verfasst: 30.11.2010 22:30
von ts-soft
Das entspricht dann aber einem String in PB. Der wird immer als Pointer übergeben und mit Nullbyte
abgeschlossen (in Unicode mit 2 Nullbytes). Also sollte ein einfaches .s richtig sein, das funktioniert
aber anscheinend nicht.
Gruß
Thomas
Re: Delphi DLL
Verfasst: 01.12.2010 05:37
von D.J.Peters
ts-soft hat geschrieben:Das entspricht dann aber einem String in PB.
Das kann ich auch bestätigen.
Ich kannte nicht den genauen Aufbau eines BP Strings daher habe ich es kurz getestet.
Code: Alles auswählen
#DLLID = 1
Result.l = OpenLibrary(#DLLID,"test01.dll")
If Result=0
MessageRequester("ERROR:","can't load 'test01.dll",#PB_MessageRequester_Ok+64)
End
EndIf
*pFunc = IsFunction(#DLLID, "GETBYTEFROMSTRING@8")
If *pFunc=0
MessageRequester("ERROR:","can't find 'GETBYTEFROMSTRING@8'",#PB_MessageRequester_Ok+64)
EndIf
OpenConsole()
test.s ="abcd"
Result = CallFunctionFast(*pFunc,test,0):PrintN(Str(Result))
Result = CallFunctionFast(*pFunc,test,1):PrintN(Str(Result))
Result = CallFunctionFast(*pFunc,test,2):PrintN(Str(Result))
Result = CallFunctionFast(*pFunc,test,3):PrintN(Str(Result))
Result = CallFunctionFast(*pFunc,test,4):PrintN(Str(Result))
Input()
CloseConsole()
CloseLibrary(#DLLID)
Byte 0-3 enthält die Zeichen und Byte 4 den 0 Terminator.
Ja Galahat jetzt bist Du an der Reihe.
Stell Dich nicht an und sage Uns doch einfach was Du falsch machst
Poste doch mal Deinen "bugy" Code und stelle sicher das Du auch die richtige DLL verwendest also die auch für VB vorgesehen ist.
Up's 04:35 wie schnell doch die Zeit am Rechner vergeht.
Gute Nacht / guten Morgen.
Grüsse Joshy
Re: Delphi DLL
Verfasst: 01.12.2010 12:59
von Galahat
So.. mit VB6 hatte ich erfolg, kann also definitiv jetzt die Codes posten. VB6 geht, PB nicht.
Selbe DLL genutzt.
Code: Alles auswählen
'***************VISUAL BASIC 6**************************************************
'IM Modul *
'**********
Declare Function Opendevice Lib "USB32IO.dll"(byval Devnumber As Byte , _
Byval Drivername As String , _
Byval Id As String , _
Byval Keyword As String) As Long
'*************
'In der Form *
'*************
Private Sub Command1_Click()
Dim DevNum As Byte
Dim DeviceID As Long
Dim S0 as String
Dim S1 as String
Dim S2 as String
S0 = "EZUSB"
S1 = ""
S2 = ""
DeviceID = OpenDevice(DevNum, S0, S1, S2)
Label1.Caption = DeviceID
End Sub
'________________________ PURE Basic 4.40 _____________________
Prototype.l USB32IO_OpenDevice(Par1.c, Par2.s,Par3.s, Par4.s)
Global OpenDevice.USB32IO_OpenDevice
Define.i hdll= OpenLibrary(#PB_Any,"USB32IO.dll")
If hdll
OpenDevice = GetFunction(hdll, "OpenDevice")
Else
MessageRequester("Error","Library Error")
EndIf
Define DevNum.c ;0 bis 31
Define DeviceID.l
Define s0.s{255} ; String mit Define und {..}, sonst gehts garnicht
Define s1.s{255}
Define s2.s{255}
S0="EZUSB"
S1=""
S2=""
DevNum = 20
DeviceID = OpenDevice(DevNum,s0,s1,s2)
Debug "Device ID " + Str(DeviceID)
Re: Delphi DLL
Verfasst: 01.12.2010 15:12
von D.J.Peters
Ich habe kein PB4.x aber das hier wäre mit PB 3.xx ok
Code: Alles auswählen
#DLLID = 1
Result.l = OpenLibrary(#DLLID,"USB32IO.dll")
If Result=0
MessageRequester("ERROR:","can't load 'USB32IO.dll' ",#PB_MessageRequester_Ok+64)
End
EndIf
*pFunc = IsFunction(#DLLID, "OpenDevice")
If *pFunc=0
MessageRequester("ERROR:","can't find 'OpenDevice'",#PB_MessageRequester_Ok+64)
EndIf
DevNumber.b = 0
DriverName.s = "EZUSB"
Id.s = ""
KeyWord.s = ""
DeviceId.l
OpenConsole()
DeviceId = CallFunctionFast(*pFunc,DevNumber,DriverName,Id,KeyWord)
PrintN(Str(DeviceId))
PrintN("press any key for quit ...")
Input()
CloseConsole()
CloseLibrary(#DLLID)
Was auch noch sein kann !
Sollte PB für DevNumber wirklich nur ein Byte auf dem Stack "pushen" dann kann es auch nicht gehen.
Denn auch ein Byte
muss 4 Bytes auf dem Stack belegen.
Das kannst du aber leicht testen in dem Du DevNumber so DevNumber
.L deklarierst.
Viel Erfolg.
Grüsse Joshy