Seite 1 von 5

Delphi DLL

Verfasst: 26.11.2010 16:45
von Galahat
Hallo Leute !

Ich habe da so ein Problem. Um es kurz zu machen: Ich versuche mich schon einige Zeit an einer Paramaterübergabe in richtung einer Delphi DLL. Das funktioniert auch. Diese DLL soll aber mit einem Treiber kommunizieren namens ezusb.sys, was sie wohl nicht tut. Die naheliegenste Vermutung ist nun, das die Strings, die die Delphi DLL erwartet, wohl nicht in dem entsprechendem Format sind.
Ich habe dazu mal die wesentlichen Zeilen herauskopiert, in der Hoffung, daß mir jemand weiterhelfen kann.

Weiter unten ist ein C# Codeschnipsel, mit dem es wohl klappen soll.

Code: Alles auswählen

Prototype.l USB32IO_OpenDevice(Par1.c, Par2.p-bstr, Par3.p-bstr, Par4.p-bstr)
.
.
Global OpenDevice.USB32IO_OpenDevice 

  Define.i hdll= OpenLibrary(#PB_Any,"USB32IO.dll")  
  
  If hdll   
    OpenDevice = GetFunction(hdll, "OpenDevice") 
.
.
.
 DeviceID= OpenDevice(Devnum,"EZUSB","","")
public static extern UInt16 OpenDevice(byte DevNumber, [MarshalAs(UnmanagedType.AnsiBStr)] string DriverName, string ID, string KeyWord);

Wie bekomme ich das Marshalling in PureBasic hin ?

Danke

Galahat

Re: Delphi DLL

Verfasst: 26.11.2010 17:10
von ts-soft
p-bstr ist unicode (das ist der Standard für 32-Bit) und die normalen APIs sehen IMHO
nichts anderes für 32-Bit vor (unter 16-Bit wird ANSI genutzt)

Probieren könntest Du, den ansi-bstr selber in den Speicher zu poken, bin mir aber nicht
sicher ob das Format, wie ich es mir denke, hinhaut:

Code: Alles auswählen

Define Text.s = "Holla, der Rucksack brennt"
Define *ansibstr = AllocateMemory(StringByteLength(Text, #PB_Ascii) + SizeOf(Integer) + SizeOf(Character))
If *ansibstr
  PokeI(*ansibstr, Len(Text))
  PokeS(*ansibstr + SizeOf(Integer),Text, -1, #PB_Ascii)
EndIf
*ansibstr jetzt an die DLL übergeben, den Text natürlich anpassen.

Musste einfach mal probieren.

Gruß
Thomas

Re: Delphi DLL

Verfasst: 26.11.2010 17:17
von Galahat
Hallo ts-soft,

danke Mann. Ich werd's ausprobieren.

Auf jeden Fall muss ich doch mal so einiges neues dazu lernen, wenn ich den Code so sehe.

Galahat

Re: Delphi DLL

Verfasst: 26.11.2010 17:18
von ts-soft
Sollte der AnsiBstr auf 255 Zeichen begrenzt sein, könntest Du auch folgendes probieren:

Code: Alles auswählen

Define Text.s = "Holla, der Rucksack brennt"
Define *ansibstr = AllocateMemory(StringByteLength(Text, #PB_Ascii) + 1 + SizeOf(Character))
If *ansibstr
  PokeI(*ansibstr, Len(Text))
  PokeS(*ansibstr + 1, Text, -1, #PB_Ascii)
EndIf 
Hierbei wird nur ein Byte für die Länge vorm String reserviert.

Re: Delphi DLL

Verfasst: 26.11.2010 17:32
von Galahat
Hierbei wird nur ein Byte für die Länge vorm String reserviert.
Eines weiß ich... die Längenangabe beträgt wohl 4 Byte.

Die Declaration in Delphi sieht so aus:
function OpenDevice(DevNumber : Byte; DriverName, ID, KeyWord : String): Word; stdcall; external 'USB32IO.DLL';

auch steht irgentwo geschrieben:
DriverName langer String ( beginnt mit 4 Byte Längenangabe )


Galahat

Re: Delphi DLL

Verfasst: 26.11.2010 17:55
von ts-soft
Da es wohl ein 32-Bit Programm ist, sollte also meine erste Variante funktionieren.
Der Prototyp sollte wohl noch angepaßt werden. In etwa (mir fehlen leider die Unterlagen):

Code: Alles auswählen

USB32IO_OpenDevice(DevNumber.b, *DriverName, ID, KeyWord.s)
Ob der erste Parameter wirklich ein Byte ist? und der letzte ein normaller String? weiß ich natürlich nicht.
Ein Ansi-String in PB entspricht PChar in Delphi.

Gruß
Thomas

Re: Delphi DLL

Verfasst: 26.11.2010 18:05
von Galahat
Ich will es mir wirklich nicht einfach machen..natürlich könnt ich Dir alles senden was ich habe...

Oder aber...
http://shop.hygrosens.com/Distribution- ... -IN32.html
und
siehe unter USB-Treiber und Dokumentation (12.11.2005)

http://www.hygrosens.com/support/download.html

Für Deine Hilfe bin ich dir sehr dankbar

Galahat

Re: Delphi DLL

Verfasst: 26.11.2010 18:35
von ts-soft
Da sind 2 verschiedene USB32IO.dll, vielleicht nimmste die aus dem Hauptordner und nicht die aus
dem Delphi-Unterordner. Die sollte mit normalen Strings umgehen können, als .s

Re: Delphi DLL

Verfasst: 29.11.2010 12:00
von Galahat
So langsam weiß ich garnicht mehr weiter...

Also Nochmal: die Delphi DLL hätte gerne einen String, der dem Delphi-String Typ : Ansi-String (oder Long-String genannt) entspricht.
Diesem String ist eine Längenangabe (4Byte lang) vorangestellt, der mit einem negativen Offset einige Bytes vor Beginn der Zeichenkette festgehalten ist.

Ich habe keinen Schimmer wie das genau aussehen soll, noch ob es denn ein Zeiger sein muss den ich der DLL übergeben soll.

Sollte der String (auf Byteniveau betrachtet) dann in etwa so aussehen ?

Text$= chr(0)+chr(0)+chr(0)+chr(5)+"EZUSB"

Einen VB-Prototypen hab ich auch noch gefunden...
Declare Function Opendevice Lib "USB32IO.dll"(byval Devnumber As Byte , _
Byval Drivername As String , _
Byval Id As String , _
Byval Keyword As String) As Long

Im Grunde sollte es doch mit einem einfachten, handelsüblichen String klappen, oder?

Galahat

Re: Delphi DLL

Verfasst: 29.11.2010 19:26
von edel
Bei den Beispielen gibt es eine Funktion, die einen normalen String in ein PascalString umwandelt.
Versuch mal folgende Procedure

Code: Alles auswählen

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
    
    PROCEDURERETURN *mem
  ENDIF
  
ENDPROCEDURE

pString = ConvertStringToPascalDLL("String")

DEBUG pString
CALLDEBUGGER
FreeMemory(pString)