![]() |
VB-Funktionen in Delphi übersetzen
Hallo,
Ich habe hier ne DLL zum chipkarten auslesen und da war ne VB demo dabei. Leider krieg ichs nicht ganz hin die funktionen zu übersetzen. könnt ihr mir dabei helfen?
Code:
die funktionen hab ich dabei so aufgefasse:
' ********************************************
' Data Types ' ******************************************** ' ' Predefined Cardtypes ' Enum SCARD_I2C_TYPE NO_PREDEFINED_CARD_PARAMETERS = 0 ' I2C cards from ST-Microelectronics: ST14C02C ST14C04C ST14E32 M14C04 M14C16 M14C32 M14C64 M14128 M14256 ' I2C cards from GEMplus: GFM2K GFM4K GFM32K ' I2C cards from Atmel: AT24C01A AT24C02 AT24C04 AT24C08 AT24C16 AT24C164 AT24C32 AT24C64 AT24C128 AT24C256 AT24CS128 AT24CS256 AT24C512 AT24C1024 I2C_TYPE_ENUM_TAIL ' must always be the last entry in this enum!! End Enum ' ' Card Parameters Structure ' Public Type SCARD_I2C_CARD_PARAMETERS ucPageSize As Byte ' Maximal number of bytes that can be written in a successive manner, in a single device select phase. ucNumberOfAddressBytes As Byte ' Number of bytes used to address the memory in the I2C card. ulMemorySize As Integer ' The size of the e2prom allocated in the card End Type ' ******************************************** ' Functions ' ******************************************** ' ' Initialize an I2C Card ' Parameters: ' hCard = Handle to current Card ' pCardParameters = Pointer to a SCARD_I2C_CARD_PARAMETERS type ' lType = Predefined Cardtype (SCARD_I2C_TYPE) ' Public Declare Function SCardI2CInit Lib "scardsyn" _ (ByVal hCard As Long, _ ByRef pCardParameters As Long, _ ByVal lType As Long) As Long ' ' Read Bytes from Card ' Parameters: ' hCard = Handle to current Card ' pbReadBuffer = Array of Bytes where data should be stored in ' ulReadBufferSize = Size of ReadBuffer ' ulAddress = Offset where read starts ' ulBytesToRead = Number of Bytes to read ' Public Declare Function SCardI2CReadData Lib "scardsyn" _ (ByVal hCard As Long, _ ByRef pbReadBuffer As Byte, _ ByVal ulReadBufferSize As Long, _ ByVal ulAddress As Long, _ ByVal ulBytesToRead As Long) As Long ' ' Write Bytes to Card ' Parameters: ' hCard = Handle to current Card ' pbWriteBuffer = Array of Bytes storing data ' ulWriteBufferSize = Size of WriteBuffer ' ulAddress = Offset where write starts ' ulBytesToWrite = Number of Bytes to write ' Public Declare Function SCardI2CWriteData Lib "scardsyn" _ (ByVal hCard As Long, _ ByRef pbWriteBuffer As Byte, _ ByVal ulWriteBufferSize As Long, _ ByVal ulAddress As Long, _ ByVal ulBytesToWrite As Long) As Long
Delphi-Quellcode:
also die SCardI2CReadData und SCardI2CWriteData funktionieren einwandfrei. die OUT und VAR prefixe hab ich mehr oder weniger hergeleitet - ich hoffe das stimmt so.
function SCardI2CInit(hCard: Cardinal; pCardParameters: Pointer; lType: SCARD_I2C_TYPE): Cardinal; stdcall; external 'scardsyn';
function SCardI2CReadData(hCard: Cardinal; out pbReadBuffer: Byte; ulReadBufferSize, ulAddress, ulBytesToRead: Cardinal): Cardinal; stdcall; external 'scardsyn'; function SCardI2CWriteData(hCard: Cardinal; var pbWriteBuffer: Byte; ulWriteBufferSize, ulAddress, ulBytesToWrite: Cardinal): Cardinal; stdcall; external 'scardsyn'; Probleme hab ich jetzt nur mit der SCardI2CInit funktion. Die gibt mir jedesmal einen fehler zurück (also ungleich 0) obwohl das eigentlich funktionieren müsste. ´die funktion verwendet auch noch 2 selbsdefinierte klassen, die hab ich mal so gemacht:
Delphi-Quellcode:
(die kommas sehen ein bisschen merkwürdig aus - so konnt ich die aber am schnellsten tippen. und zum testen ja ok.. :)
type SCARD_I2C_CARD_PARAMETERS=record
ucPageSize: Cardinal;// ' Maximal number of bytes that can be written in a successive manner, in a single device select phase. ucNumberOfAddressBytes: Byte;// ' Number of bytes used to address the memory in the I2C card. ulMemorySize: Integer //' The size of the e2prom allocated in the card end; type SCARD_I2C_TYPE=(NO_PREDEFINED_CARD_PARAMETERS = 0, ST14C02C, ST14C04C , ST14E32 , M14C04 , M14C16 , M14C32 , M14C64 , M14128 , M14256 , //' I2C car,ds from GEMplus: GFM2K , GFM4K , GFM32K, //' I2C cards from Atmel: AT24C01A , AT24C02 , AT24C04 , AT24C08 , AT24C16 , AT24C164 , AT24C32 , AT24C64 , AT24C128 , AT24C256 , AT24CS128 , AT24CS256 , AT24C512 , AT24C1024 , I2C_TYPE_ENUM_TAIL ); der code um die funktionsausführung bei vb sieht so aus:
Code:
mein code sieht so aus:
Dim rc As Long
Dim CardParameters As SCARD_I2C_CARD_PARAMETERS Dim pCardParameters As Long Dim lType As Long ' Type (see SCardI2C.bas "Predefined Cardtypes") lType = NO_PREDEFINED_PARAMETERS If I2CTYPE.Text = "ST14C02C" Then lType = ST14C02C If I2CTYPE.Text = "ST14C04C" Then lType = ST14C04C If I2CTYPE.Text = "ST14E32" Then lType = ST14E32 If I2CTYPE.Text = "M14C04" Then lType = M14C04 If I2CTYPE.Text = "M14C16" Then lType = M14C16 If I2CTYPE.Text = "M14C32" Then lType = M14C32 If I2CTYPE.Text = "M14C64" Then lType = M14C64 If I2CTYPE.Text = "M14128" Then lType = M14128 If I2CTYPE.Text = "M14256" Then lType = M14256 If I2CTYPE.Text = "GFM2K" Then lType = GFM2K If I2CTYPE.Text = "GFM4K" Then lType = GFM4K If I2CTYPE.Text = "GFM32K" Then lType = GFM32K If I2CTYPE.Text = "AT24C01A" Then lType = AT24C01A If I2CTYPE.Text = "AT24C02" Then lType = AT24C02 If I2CTYPE.Text = "AT24C04" Then lType = AT24C04 If I2CTYPE.Text = "AT24C08" Then lType = AT24C08 If I2CTYPE.Text = "AT24C16" Then lType = AT24C16 If I2CTYPE.Text = "AT24C164" Then lType = AT24C164 If I2CTYPE.Text = "AT24C32" Then lType = AT24C32 If I2CTYPE.Text = "AT24C64" Then lType = AT24C64 If I2CTYPE.Text = "AT24C128" Then lType = AT24C128 If I2CTYPE.Text = "AT24C256" Then lType = AT24C256 If I2CTYPE.Text = "AT24CS128" Then lType = AT24CS128 If I2CTYPE.Text = "AT24CS256" Then lType = AT24CS256 If I2CTYPE.Text = "AT24C512" Then lType = AT24C512 If I2CTYPE.Text = "AT24C1024" Then lType = AT24C1024 ' get pointer do CardParameters pCardParameters = VarPtr(CardParameters) ' Init rc = SCardI2CInit(hCard, pCardParameters, lType) If rc <> OKERR_OK Then MESSAGETEXT.Text = HandleError(rc) Exit Sub End If MESSAGETEXT.Text = "InitI2C successfull"
Delphi-Quellcode:
wobei ich mir jetzt nicht ganz sicher bin ist des mit dem pointer (' get pointer do CardParameters) und ob der typ "Long" richtig umgesetzt ist mir Cardinal und auch ob das mit den definierten classen (record und enum) so ganz richtig ist.
var
rc: Cardinal; CardParameters: SCARD_I2C_CARD_PARAMETERS; pCardParameters: Pointer; lType: SCARD_I2C_TYPE; begin { ' Type (see SCardI2C.bas "Predefined Cardtypes") lType = NO_PREDEFINED_PARAMETERS If I2CTYPE.Text = "ST14C02C" Then lType = ST14C02C If I2CTYPE.Text = "ST14C04C" Then lType = ST14C04C If I2CTYPE.Text = "ST14E32" Then lType = ST14E32 If I2CTYPE.Text = "M14C04" Then lType = M14C04 If I2CTYPE.Text = "M14C16" Then lType = M14C16 If I2CTYPE.Text = "M14C32" Then lType = M14C32 If I2CTYPE.Text = "M14C64" Then lType = M14C64 If I2CTYPE.Text = "M14128" Then lType = M14128 If I2CTYPE.Text = "M14256" Then lType = M14256 If I2CTYPE.Text = "GFM2K" Then lType = GFM2K If I2CTYPE.Text = "GFM4K" Then lType = GFM4K If I2CTYPE.Text = "GFM32K" Then lType = GFM32K If I2CTYPE.Text = "AT24C01A" Then lType = AT24C01A If I2CTYPE.Text = "AT24C02" Then lType = AT24C02 If I2CTYPE.Text = "AT24C04" Then lType = AT24C04 If I2CTYPE.Text = "AT24C08" Then lType = AT24C08 If I2CTYPE.Text = "AT24C16" Then lType = AT24C16 If I2CTYPE.Text = "AT24C164" Then lType = AT24C164 If I2CTYPE.Text = "AT24C32" Then lType = AT24C32 If I2CTYPE.Text = "AT24C64" Then lType = AT24C64 If I2CTYPE.Text = "AT24C128" Then lType = AT24C128 If I2CTYPE.Text = "AT24C256" Then lType = AT24C256 If I2CTYPE.Text = "AT24CS128" Then lType = AT24CS128 If I2CTYPE.Text = "AT24CS256" Then lType = AT24CS256 If I2CTYPE.Text = "AT24C512" Then lType = AT24C512 If I2CTYPE.Text = "AT24C1024" Then lType = AT24C1024 } lType := ST14C02C; //' get pointer do CardParameters pCardParameters := @CardParameters; //' Init rc := SCardI2CInit(hCard, pCardParameters, lType); If rc <> 0 Then begin edit1.Text := ('error'); exit; end; edit1.Text := 'InitI2C successfull'; end; Danke schonmal im Vorraus! mfg. |
Re: VB-Funktionen in Delphi übersetzen
Hi,
wow, erschlag einen doch mit Quellcode. Könntest du das bitte beim nächsten mal eher anhängen bei der Länge und nur die stellen posten, die wirklich relevant sind? Danke! Aber bin es mal durchgegangen und sehe da einen Fehler, vielleicht ist der dir ja nur beim schnellen abtippen oder so passiert. Hier
Code:
steht für ucPageSize As Byte, hier
Public Type SCARD_I2C_CARD_PARAMETERS
ucPageSize As Byte ' Maximal number of bytes that can be written in a successive manner, in a single device select phase. ucNumberOfAddressBytes As Byte ' Number of bytes used to address the memory in the I2C card. ulMemorySize As Integer ' The size of the e2prom allocated in the card End Type
Delphi-Quellcode:
ist ein Cardinal draus gewurden. Eins von beiden stimmt entsprechend nicht.
type SCARD_I2C_CARD_PARAMETERS=record
ucPageSize: Cardinal;// ' Maximal number of bytes that can be written in a successive manner, in a single device select phase. ucNumberOfAddressBytes: Byte;// ' Number of bytes used to address the memory in the I2C card. ulMemorySize: Integer //' The size of the e2prom allocated in the card end; Was die Datentypen angeht, so variiert es etwas, je nachdem ob du VB oder VB.Net benutzt (bzw. das Beispiel). Im "alten" VB ist ein integer 16-Bitig und ein small-Int und ein long 32-bitig und damit ein Integer (Byte ist Byte und auch wirklich unsigned). Unter VB.Net sieht die Sache etwas anders aus, hier wurde ein integer auf 32 bit vergrößert (= Integer) und ein long entspricht einem Int64. Musst du gucken was bei dir der Fall ist. Gruß Der Unwissende |
Re: VB-Funktionen in Delphi übersetzen
hi,
vielen dank. das mit dem byte und cardinal ist mir auch aufgefallen :) ich hab jetzt noch die variablen der funktion alle "normal" deklariert, d.h. ohne prefix. dann hab ich noch pCardParameters durch @CardParameters ersetzt. jetzt funktionierts - wenn auch merkwürdig. wenn ich z.b. hinschreibe
Delphi-Quellcode:
dann bricht er jedes mal ab.
rc := SCardI2CInit(hCard, @CardParameters, lType);
If rc <> 0 Then begin edit1.Text := ('error'); exit; end; wenn ich aber schreib
Delphi-Quellcode:
funktionierts (fast) immer. wenn ich bei der funktion anstatt stdcall "safecall" angeb dann sagt er bei der ersten variante dasses ein safecall fehler gab und bei der version unten gibts kein fehler.
rc := SCardI2CInit(hCard, @CardParameters, lType);
inttostr(rc); If rc <> 0 Then begin edit1.Text := ('error'); exit; end; ich hab jetzt mal noch eine combobox eingefügt und wie beim vb beispiel noch so viele if..then sachen davpr gemacht wo er dem lType den wert zuweist. jetzt funktionierts immer. dennoch ärgerlich dass ich nicht weis worans liegt. ps: ich habs "alte" vb drauf glaub. also halt visual studio 6. Zitat:
|
Re: VB-Funktionen in Delphi übersetzen
Zitat:
Was deinen Rückgabecode angeht, hast du rc denn initialisiert? Solltest du machen, da du nicht weißt was für ein Code zurück kommt. Am besten mit einem festen Wert. Bist du dir denn sicher, dass 0 = Kein Fehler ist? Im VB-Programm wird eine Konstante benutzt. Wenn du eine Liste der Fehlercodes hast, solltest du schauen, ob es einen Eintrag zu dem zurückgegebenen Code gibt und ob dieser immer gleich bleibt (also rc einmal mit 0, einmal mit -1 initialisieren und schauen ob immer das gleiche nach dem Aufruf drin steht). Ansonsten ist es eigentlich sehr beliebt auch positive Fehlercodes für Success und Negative für Fehler zu nehmen. Gruß Der Unwissende |
Re: VB-Funktionen in Delphi übersetzen
Ach nochwas, du solltest bei deinem LType ruhig sicherstellen, dass es sich hier um Integerwerte handelt. Ich denke zwar, dass Delphi dass intern eh übernimmt, aber es kann ja nichts schaden. Caste einfach deinen übergebenen LType in ein Integer.
Gruß Der Unwissende |
Re: VB-Funktionen in Delphi übersetzen
RC ist ein cardinal, der kann nicht negativ sein.
ich hab den auch schonmal davor gesetzt aber hat auch nicht gewirkt. |
Re: VB-Funktionen in Delphi übersetzen
RC ist ein Long (in VB) und damit ein Integer in Delphi, der kann durchaus negativ werden. Du solltest wirklich die Datentypen anpassen, sonst kannst du dort keine Fehler ausschließen. Wie gesagt/gefragt, ist dir der Wert von OKERR_OK bekannt? Und ist der sicher null?
|
Re: VB-Funktionen in Delphi übersetzen
okerr_ok ist null.
naja drum hab ich ja gefragt, ob Long vergleichbar mit Integer oder Cardinal ist. hab jetzt mal alles abgeändert in Integers anstatt Cardinals, hat aber auch nix gebracht. jetzt hab ich noch in der funktion als typ bei "lType" Integer angegeben anstat SCARD_I2C_TYPE und den wert mit Integer() an die funktion übergeben - jetzt funktionierts! danke! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz