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.