Einzelnen Beitrag anzeigen

taveuni

Registriert seit: 3. Apr 2007
Ort: Zürich
534 Beiträge
 
Delphi 11 Alexandria
 
#1

32/64bit DLL und Platform unterschiedliches Verhalten

  Alt 27. Sep 2023, 16:10
Sorry für den möglicherweise verwirrenden Titel und mein Unverständnis in diesem Fall.
Für ein Subsystem verwenden wir seit Jahren eine 32bit (C-) DLL API des Herstellers. Diese konsumieren wir mit einer Delphi 32bit Version.
Nun ist die 32bit API abgekündigt und wir migrieren auf eine Delphi 64bit Applikation und verwenden die 64bit API. Nun bin ich auf ein Problem im Callback gestossen.
Als Beispiel eine Methode und das Callback. Die C Header Datei sieht so aus:

Code:

/**
* @brief Structure holding basic input parameters
*/
typedef struct dlm_basicParametersStructure
{
   unsigned long ulFunctionID;                                    ///< Function ID
   int SessionHandle;                                       ///< Session ID
} dlm_basicParameters;



DLM_API int DLM_CALL_CONV dlm_getStreamingServerConfiguration(
   int SessionHandle,
   void (DLM_CALL_CONV *callback)(void *pParameters, void *pResult, void *pInput),
   void *pInput
);

/**
* Structure holding a callback result
*/
typedef struct XmlCallbackResult_
{
   int32_t iResult;                  ///< Result
   const char *xml;                  ///< Concomitant XML
} XmlCallbackResult;
Der *pResult Parameter enthält dann in diesem Fall den int32 und ein XML.

In Delphi ist das ganze so deklariert:

Delphi-Quellcode:
  Tdlm_getStreamingServerConfiguration = function(SessionHandle: Integer;
                                                   pParameters: pointer;
                                                   pInput: Pointer) : Integer; stdcall;

  TDlmXmlCallbackResult = packed record
    iResult : Int32;
    Xml : PAnsiChar;
  end;
  PDlmXmlCallbackResult = ^TDlmXmlCallbackResult;


  TDlmBasicCallbackData = packed record
    ulFunctionId : Cardinal;
    iSessionHandle : Integer;
  end;
  PDlmBasicCallbackData = ^TDlmBasicCallbackData;
Beim Empfang des Callbacks passiert folgendes:

Delphi-Quellcode:
procedure TDlmApiCallbackSingleton.ApiCallback(pParameters, pResult, pInput: pointer);
var
  p: PDlmBasicCallbackData;
  Res: Integer;
  XmlRes: PDlmXmlCallbackResult;
begin
    p:= pParameters;
    Res:= pInteger(pResult)^;
    TLogger.Log.Debug('Dlm callback event. FuncId: %d, Session: %d, ErrCode: %d',[p.ulFunctionId, p.iSessionHandle, Res],'DlmSdk');

    case p.ulFunctionId of
    res_getStreamingServerConfiguration:
    begin
      XmlRes:= PDlmXmlCallbackResult(pResult);
      var i:= XMLRes.iResult; // 32 und 64bit korrekter Wert
      if XMLRes.XML = 'then // Zugriffserverletzung 64bit
    end;
Nun habe ich eine TestApplikation mit einer 32bit und einer 64bit Plattform erstellt welche jeweils die korrekte API konsumiert.
Im 32bit Kompilat erhalte ich den XMLRes.XML eine PAnsichar mit einem XML. Im 64bit Kompilat erhalte ich eine Zugriffsverletzung. Was mache ich falsch?
Vermutlich ist TDlmXmlCallbackResult und/oder TDlmBasicCallbackData falsch deklariert? Und zufälligerweise hats bei 32bit geklappt?
Ich habe schon mit Ausrichtung der Recordfelder experimentiert. Leider ohne Erfolg. Kann mir jemand helfen?
Die obige Aussage repräsentiert meine persönliche Meinung.
Diese erhebt keinen Anspruch auf Objektivität oder Richtigkeit.

Geändert von taveuni (27. Sep 2023 um 16:12 Uhr)
  Mit Zitat antworten Zitat