![]() |
DLL Schnitstelle
Hallo,
Seit mehreren Tagen brüte ich nun schon über folgendes: Als nicht DLL und auch nicht C/C++ Spezi habe ich hier eine Frage zum Aufruf einer DLL Funktion aus Delphi. Hier die ‘c’ Seite:
Code:
Wie würde das Delphi Gegenstück dazu aussehen?
SE_API_IMPL(se_result_t, se_getCertificationId)(char **certificationId, uint32_t *certificationIdLength)
Die DLL function spreche ich in Delphi so an
Delphi-Quellcode:
Sicher ein Klacks komme aber hier nicht weiter und wäre daher sehr dankbar für eine Hint oder besser
function se_getCertificationId(var certificationId: PAnsiChar; certificationIdLength: Cardinal): Cardinal; cdecl; external 'se-api-c.dll';
Code:
Vielen Dank für jegliche Hilfe
In VB.Net sieht es so aus. Brauche aber das Delphi äquivalent.
' Get certification ID as assigned by BSI ("BSI-K-TR-0374-2019" for cryptovision TSE). ' @param[out] certificationId Returned identifier string (Not null terminated) [REQUIRED] ' If successfully executed, the buffer has to freed by the function caller [@ref se_free()]. ' @param[out] certificationIdLength length of the returned identifier string [REQUIRED] ' @return @ref ExecutionOk execution of the function has been successful ' @return @ref ErrorSECommunicationFailed Secure Element communication failed ' @since v2.1 ' se_result_t se_getCertificationId(char**certificationId, uint32_t*certificationIdLength); <DllImport("se-api-c.dll", EntryPoint:="se_getCertificationId", CharSet:=CharSet.Ansi)> Private Function GetCertificationIdSub(ByRef certificationId As IntPtr, ByRef certificationIdLength As Integer) As SeReturnCode End Function Public Structure GetCertificationIdReturn Public ReturnCode As SeReturnCode Public certificationId As String End Structure Public Function GetCertificationId() Dim ReturnStruct As GetCertificationIdReturn Dim certificationId As IntPtr Dim certificationIdLength As Integer ReturnStruct.ReturnCode = GetCertificationIdSub(certificationId, certificationIdLength) If SeReturnCode.ExecutionOk = ReturnStruct.ReturnCode Then ReturnStruct.certificationId = PtrToStringAnsiAndFree(certificationId, certificationIdLength) Else ReturnStruct.certificationId = String.Empty End If Return ReturnStruct End Function Heiri |
AW: DLL Schnitstelle
Code:
SE_API_IMPL(se_result_t, se_getCertificationId)(char **certificationId, uint32_t *certificationIdLength)
-> declare se_getCertificationId as function (pointer to pointer to char, pointer to uint32_t) returning se_result_t
Delphi-Quellcode:
type
se_result_t = Cardinal; //? musst du in der Doku gucken was se_result_t sein soll PUInt32 = ^System.UInt32; PPByte = ^System.PByte; function se_getCertificationId(var certificationId: PAnsiChar; certificationIdLength: PUInt32): se_result_t ; cdecl; external 'se-api-c.dll'; //oder function se_getCertificationId(var certificationId: PAnsiChar; var certificationIdLength: UInt32): se_result_t ; cdecl; external 'se-api-c.dll'; // probiere auch mal so, wenn certificationID eh ne Zahl zwischen 0 und 255 laut Doku ist: function se_getCertificationId(var certificationId: PByte; var certificationIdLength: UInt32): se_result_t ; cdecl; external 'se-api-c.dll'; // gerne auch function se_getCertificationId(certificationId: PPByte; certificationIdLength: PUInt32): se_result_t ; cdecl; external 'se-api-c.dll'; |
AW: DLL Schnitstelle
Oh vielen Dank für deine Antwort.
- se_result_t enthält ein Fehler Code falls es nicht korrekt durch läuft 0. Bei mir kommt immer 'fehlender Parameter' - var certificationId: PAnsiChar sollte die gesuchte ID zurückliefern bei der VB Version bekomme ich das hier 'BSI-K-TR-0000-2019' bei Delphi eben noch nicht! Humm Heiri |
AW: DLL Schnitstelle
Zeig doch mal deinen Quelltext, wo du die Funktion aufrufst.
Hast du alle beide PAnsiChar-Varianten mal durchprobiert? EDIT: Ändere mal bei se_result_t von Cardinal zu einen Int32. Da du nicht die Definition aus dem C-Header gepostet hast, nehme ich einfach mal an, dass da ggf. auch negative Werte rausfallen können?! |
AW: DLL Schnitstelle
Sicher, dass es cdecl oder nicht vielleicht stdcall ist?
Wie sieht denn SE_API_IMPL aus? [OT] Hach, wie schön es bald mit 64 Bit wird ... da gibt's nur noch eine Convention (die fast wie bei unserem Pascal aussieht :stupid:) |
AW: DLL Schnitstelle
Vielen Dank für eure Hilfe versuche.
Jetzt habe ich auch begriffen wie man hier korrekt Code schnipsel einfügt! Insgesammt sind es über 50 Funktionen, die meisten sind ok nur 'se_getCertificationId' will nicht so recht. So sehen die Einbindungen der DLL Funktionen aus:
Delphi-Quellcode:
Und hier die Aufrufe dazu:
function se_getImplementationVersionString(): PAnsiChar; cdecl; external 'se-api-c.dll';
function se_getImplementationVersion(): PAnsiChar; cdecl; external 'se-api-c.dll'; function se_getUniqueId(): PAnsiChar; cdecl; external 'se-api-c.dll'; function se_getCertificationId(var certificationId: PAnsiChar; certificationIdLength: Cardinal): Cardinal; cdecl; external 'se-api-c.dll'; function se_getLifeCycleState(var lcs: Cardinal): Cardinal; cdecl; external 'se-api-c.dll'; function se_getMaxNumberOfClients(var maxNumberClients: Cardinal): Cardinal; cdecl; external 'se-api-c.dll';
Delphi-Quellcode:
Und die Implementation dazu (Hier mache ich eiregend etwas falsch und komme nicht dahinter was wie gemacht werden muss.)
function SeGetPinStatus(var PINState: Cardinal): TSeReturnCode;
function SeGetUniqueId: string; function SeGetCertificationId(var CertificationId: string): TSeReturnCode; function SeAuthenticateUser(UserId: string; PIN: array of Byte; var AuthenticationResult: TSeAuthenticationResult; var RemainingRetrie: ShortInt): TSeReturnCode; function SeGetLifeCycleState(var lcs: TSeLifeCycleState): TSeReturnCode;
Delphi-Quellcode:
Vielen Dank schon mal für die Auswertung meiner Angaben und etwelche wie was wo zu tun ist Hints!
function SeGetCertificationId(var CertificationId: string): TSeReturnCode;
var PCertificationID: PAnsiChar; PCurrent: PAnsiChar; CertificationIDLength: Cardinal; i: Cardinal; begin PCertificationID := nil; // VB übergibt PCertificationID = &H000000000 und CertificationIDLength = 0 Result := TSeReturnCode(se_getCertificationID(PCertificationID, CertificationIDLength)); // Zurück bekomme ich im VB Code BSI-K-TR-0000-2019 für PCertificationID und 18 für CertificationIDLength // Mit Delphi und der Zeile oben einen Fehlercode // Da werde ich die Parameter entsprechend übernehme sobalt // mir se_getCertificationID was brauchbares liefert. // Aktuell erhalte ich hier Access Violation oder der Result code sagt // etwas von 'missing parameter' end; |
AW: DLL Schnitstelle
Das.
Delphi-Quellcode:
function se_getCertificationId(certificationId: PPByte; certificationIdLength: PUInt32): se_result_t ; cdecl; external 'se-api-c.dll';
kann nur ins leere laufen denn ByRef ist immer var in Delphi ByVal ist einfach ein Parameter der übergeben wird. Und dann was denn nun?
Delphi-Quellcode:
oder
PCertificationID: PAnsiChar;
Delphi-Quellcode:
beides geht auf keinen Fall wenn schon dann
CertificationId: string
Delphi-Quellcode:
entfernen und Rückgabe ist
PCertificationID: PAnsiChar;
Delphi-Quellcode:
CertificationId: string
Wenn CertificationId ein Pointer auf AnsiString ist (siehe PtrToStringAnsiAndFree) dann bitte
Delphi-Quellcode:
und nicht
CertificationID: PAnsiChar
Delphi-Quellcode:
.
CertificationID: string
Alles durcheinander geworfen sorry. Siehe
Delphi-Quellcode:
function SeGetCertificationId(var CertificationId: string): TSeReturnCode;
und
Delphi-Quellcode:
function SeGetCertificationId(var CertificationId: PAnsiChar): TSeReturnCode;
Die Definition
Delphi-Quellcode:
PCertificationID: PAnsiChar;
ist dann unsinnig. Korrekt wäre das ohne Gewähr.
Delphi-Quellcode:
Nochmal
function SeGetCertificationId(var CertificationId: PAnsiChar): TSeReturnCode;
var // PCertificationID: PAnsiChar; // Quatsch // PCurrent: PAnsiChar; wird nicht verwendet CertificationIDLength: Cardinal; // i: Cardinal; wird nicht verwendet begin // PCertificationID := nil; Quatsch // VB übergibt PCertificationID = &H000000000 und CertificationIDLength = 0 Result := TSeReturnCode(se_getCertificationID(CertificationID, CertificationIDLength)); // Zurück bekomme ich im VB Code BSI-K-TR-0000-2019 für PCertificationID und 18 für CertificationIDLength // Mit Delphi und der Zeile oben einen Fehlercode // Da werde ich die Parameter entsprechend übernehme sobalt // mir se_getCertificationID was brauchbares liefert. // Aktuell erhalte ich hier Access Violation oder der Result code sagt // etwas von 'missing parameter' end;
Delphi-Quellcode:
oder
var certificationId: PAnsiChar
Delphi-Quellcode:
entscheide dich einfach mal.
var certificationId: string
Delphi-Quellcode:
function se_getCertificationId(var certificationId: PAnsiChar; certificationIdLength: Cardinal): Cardinal; cdecl; external 'se-api-c.dll';
|
AW: DLL Schnitstelle
Das PAnsiChar <> String UnicodeString (seit Delphi 2009) wollte ich auch grade ansprechen.
Zitat:
Wieso ignoriert hier jemand die Compilerwarnungen? Und wenn VB das macht, warum du nicht auch? CertificationIDLength wurde nicht initialisiert PCertificationID = string -> PAnsiChar Und wenn VB das macht, dann vermutlich um erstmal im Result die nötige Länge abzufragen, welche für einen weiteren Aufruf benutzt wird. Man kann alternativ auch blind den Speicher auf eine Länge festlegen, die "immer" ausreichend wäre, und anschließend auf das zurück ändern, was wirklich benutzt wurde. Probleme: * falsche Typen (ANSI <> Unicode) * falsche Benutzung (ungültige Parameter) Entweder intern mit ANSI arbeiten und umkopieren oder die umgebende Funktion mit einem AnsiString bauen. |
AW: DLL Schnitstelle
Vielen Dank venice2,
hilft mir schon mal weiter.
Delphi-Quellcode:
function SeGetCertificationId(var CertificationId: string): TSeReturnCode;
var PCertificationID: PAnsiChar; PCurrent: PAnsiChar; CertificationIDLength: Cardinal; i: Cardinal; begin PCertificationID := nil; // VB übergibt PCertificationID = &H000000000 und CertificationIDLength = 0 Result := TSeReturnCode(se_getCertificationID(PCertificationID, CertificationIDLength)); // Zurück bekomme ich im VB Code BSI-K-TR-0000-2019 für PCertificationID und 18 für CertificationIDLength // Der var Parameter im Header der Funktion sollte für meine Zwecke schon [B]string[/B] sein // Dann müsste ich halt dies entsprechend konvertieren. // Zum Beispiel so CertificationId := String(AnsiString(PCertificationID)); // Oder sehe ich das falsch? // Nur eben die Funktion se_getCertificationID liefert nichts brauchbares in Delphi // Also müsste wohl PCertificationID: PAnsiChar; anders definiert sein oder anders // initialisiert werden, [B]da liegt offenbar mein Problem. [/B] end; |
AW: DLL Schnitstelle
Ich würde den Kram so umschreiben wenn für CertificationIDLength keine Rückgabe erforderlich ist.
Zitat:
Delphi-Quellcode:
function SeGetCertificationId(var CertificationId: PAnsiChar; CertificationIDLength: Cardinal): TSeReturnCode;
Delphi-Quellcode:
EDIT:
if SeGetCertificationId(CertificationId, 0) = ExecutionOk then
bla, bla
Delphi-Quellcode:
CertificationId := String(AnsiString(PCertificationID)); // Oder sehe ich das falsch?
Ja. Du benötigst die Variable PCertificationID nicht! Die Rückgabe ist ein Pointer auf Ansistring (PAnsiChar) siehe (PtrToStringAnsiAndFree) kein String! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:18 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