Seite 5 von 5

Re: Delphi DLL

Verfasst: 01.12.2010 20:27
von Galahat
So..hab ich gemacht. Ich benutze nie wieder c ;-)
Ich konzentriere mich jetzt mal aufs b.

Auch hier ist ein Phenomen zu verzeichnen.
wenn Devnum >31 ist, läuft alles glatt. Keine Fehlermeldung. Bin ich unter 31, dann gibts Fehler.

ganz kleinlaut: mit .c ist es genauso

Ich kann alles im Prototypen ausprobieren, wie auch bei der Devnum. Ist Devnum>31 ist alles in Butter.

mmh?

Re: Delphi DLL

Verfasst: 01.12.2010 21:00
von ts-soft
Ich hab jetzt leider die Anleitung nicht mehr, aber da stand irgendwas von evtl. bereits belegten
nummern, durch das OS. Wichtig war dabei wohl das anschließen der Hardware vor dem Booten
oder so ähnlich. Hab es nur oberflächlich gelesen, da mir sowieso die Hardware fehlt, aber ich denke
der Fehler liegt jetzt nicht mehr im PB-Source.

Gruß
Thomas

Re: Delphi DLL

Verfasst: 01.12.2010 21:06
von Galahat
Das mit dem belegten Nummern ist nicht das Problem.

Ich kann jederzeit mit der VB.exe nachgucken.

Re: Delphi DLL

Verfasst: 01.12.2010 23:08
von Galahat
...und es sind doch die Strings, die den Ärger machen.

Der Grund: Ich habe auch einen Funktionsaufruf "GetDeviceError" getestet, der mir immer einem passenden und plausiblen Fehlercode gesendet hat, sobald ich mit mit der Devnum >31 kam. ...sogar mit .c ;-)
Devnum ist also völlig okay.

Weiter las ich, was VB bei Calls auf DLL mit Byref Strings so anstellt. Also z.B. wie hier:

Declare Function Opendevice Lib "USB32IO.dll"(byval Devnumber As Byte , _
Byval Drivername As String , _
Byval Id As String , _
Byval Keyword As String) As Long

VB arbeitet intern mit BSTR. VB übermittelt tatsächlich jedoch einen Zeiger auf jene Zeichenkette, die er aber zuvor zu einem String a la' C mit NULL-Zeichen konvertiert hat, um natürlich zu den meist in C geschriebenen DLL kompatibel zu sein.

Trotzdem bin ich verwirrt.

Re: Delphi DLL

Verfasst: 01.12.2010 23:25
von ts-soft
Galahat hat geschrieben:...und es sind doch die Strings, die den Ärger machen.....

VB übermittelt tatsächlich jedoch einen Zeiger auf jene Zeichenkette, die er aber zuvor zu einem String a la' C mit NULL-Zeichen konvertiert hat, um natürlich zu den meist in C geschriebenen DLL kompatibel zu sein.
Also ein Zeiger auf String ala C mit null am ende entspricht doch einem PB String :mrgreen:
Ein ganz normaler Zeiger auf einen nullterminierten String. Den gibt es in PB als ASCII oder
Unicode String, je nach Compiler-Einstellung. Deshalb ja im Prototyp "Par2.p-ascii" und nicht "Par2.s", weil dies ja nur im ASCII-Modus funktionieren würde.

Warum sollte also der korrekte String Ärger machen?

Re: Delphi DLL

Verfasst: 02.12.2010 20:13
von Galahat
Warum sollte also der korrekte String Ärger machen?


Weil ich Recht habe...korregiere HATTE :D

Männer !

An dieser Stelle möchte ich bekannt geben, daß nach weniger als 5 Minuten nach dem Rechnerstart (minus Windows-Boot-Time ;_)) es endlich geklappt hat.
Also an alle die sich Gedanken dazu gemacht haben, ganz besonders ts-soft, Joshi und edel, ein dickes DANKESCHÖN !

Die Lösung hatte ich doch schon eigendlich. Woran lag's ?

Die DLL braucht einen Zeiger auf einen ASCII String mit vorangestellter 4 Byte Längenangabe. Der Zeiger soll auf's erste Zeichen zeigen. ZEICHEN, nicht das 1. Byte. Ich Trottel. Nicht nur sagen..machen ! ...sowas blödes

Hier der Code:

Code: Alles auswählen

EnableExplicit

Prototype.i USB32IO_OpenDevice(Par1.c , Par2.i, Par3.i, Par4.i)

Define OpenDevice.USB32IO_OpenDevice 

Define.i hdll= OpenLibrary(#PB_Any, "USB32IO.dll")   
If hdll   
  OpenDevice = GetFunction(hdll, "OpenDevice")
Else   
  MessageRequester("Error", "Library Error")
  End
EndIf

;#######################################################################################

Procedure ConvertStringToPascalDLL(AnsiString.s)
 
  Protected len
  Protected *mem.long
  len = Len(AnsiString)
  *mem = AllocateMemory(len + 5) 
  If *mem           
    PokeS(*mem + SizeOf(long), AnsiString) 
    *mem\l = len
    Debug Str(len)
    ProcedureReturn *mem+4     ;POINTER muss aufs erste ASCII Zeichen
  EndIf
  
EndProcedure


Define DevNum.c ;0 bis 31
Define DeviceID.i  
Define.s s0, s1, s2
Define  *Z0.i,*Z1.i,*Z2.i

*Z0 = ConvertStringToPascalDLL("EZUSB")
*Z1 = ConvertStringToPascalDLL("")
*Z2 = ConvertStringToPascalDLL("")


DeviceID = OpenDevice(DevNum, *Z0, *Z1,*Z2) 
Debug "Device ID  "  + Str( DeviceID) 

PS: und es geht auch mit :praise: .c


Galahat

Re: Delphi DLL

Verfasst: 02.12.2010 20:36
von ts-soft
Die Idee hatte ich auch schon, hielt sie aber für zu verwegen :mrgreen:
Galahat hat geschrieben:PS: und es geht auch mit :praise: .c
Aber nur wenn Compileroptionen auf ASCII steht, weil .c ändert seine größe von byte auf word in Unicode! Deshalb ist es einfach die falsche Wahl.

Schön wenn es endlich geklappt hat,

gruß
Thomas

Re: Delphi DLL

Verfasst: 02.12.2010 21:05
von D.J.Peters
Klingelt es da nicht im Köfpchen :lol:

pointer - 8 ist der ReferenzZähler
pointer - 4 ist die Längenangabe
pointer - 0 ist der Zeiger auf das erste Zeichen

Code: Alles auswählen

Structure DELPHISTRING
  RefCounter.l
  StringSize.l
  *pChars
EndStructure
Wo ist denn da der Zusammenhang zum VB String BYVAL ????????????????????????????????????????????

Re: Delphi DLL

Verfasst: 03.12.2010 23:15
von Galahat
Klingelt es da nicht im Köfpchen
pointer - 8 ist der ReferenzZähler
pointer - 4 ist die Längenangabe
pointer - 0 ist der Zeiger auf das erste Zeichen
Ne, hier klingelt nichts, kann auch nicht. siehe im Quellcode den erzeugten String. /:->
Wo ist denn da der Zusammenhang zum VB String BYVAL ????????????????????????????????????????????
Ich gehe mal davon aus, daß du ein aufmerksamer Leser bist. Aber ich erkläre es dir gerne nochmal kurz, was VB ByVal String mit der ganzen Sache zu tun hat. Auf gehts:

In der Dokumentation gab es Beispieldeklarationen in VB, darunter auch eben jene OPENDEVICE, die an den betrefflichen Stellen mit byVal as Sting funktionieren sollt. Darauf hin hab ich das auch mit VB getestet, was auch funktionierte.
Es stellte sich dann also die Frage, "was macht Visual Basic da wirklich?".
Fakt ist, Strings die in VB mit ByVal übergeben werden, sind eine Ausnahme bei der Parameterübergabe. Was macht VB: VB arbeitet mit BSTR unicode. VB macht daraus ASCII. BSTR hat Längenangabe - der resultierende String dann auch. Weiter hin stellt VB einen Zeiger auf das erste DATENBYTE, also an Stelle 4 (von 0 ausgegangen). Und nun kommts: VB übergibt den Zeiger, und keinen Sting. Als ich das endlich sicher wusste, konnte ich genau jenen Weg einschlagen, um diese Ergebnis zu erzielen. Darin liegt einfach der Zusammenhang. Im Grunde genommen sorgte das erst a) für sicherheit in welcher Weise es funktionieren muss und b) konnte ichn auch die DLL-Frage lösen.

Ich bin mir auch weiter sicher (ist ja keine Schande das zumindest jetzt zu erkennen), schon recht früh die Lösung gehabt zu haben, habe dabei aber noch einen Gedankenfehler bei DeviceID in DevNum gehabt. Sowas passiert hat mal, wenn man aus einem Code Passagen aus ihren Zusammenhängen löst.

Sei dir aber meines Dankes gewiss.

Galahat