Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi C nach Delphi (Pascal) Konvertierungsproblem (https://www.delphipraxis.net/148081-c-nach-delphi-pascal-konvertierungsproblem.html)

MiniMatrix 22. Feb 2010 10:27


C nach Delphi (Pascal) Konvertierungsproblem
 
Hi

Ich versuche mich gerade bei der Portierung eines C Quellcodes nach Delphi (Pascal) und stoße da leider an meine Verständnisgrenzen und hoffe, es kann mir jemand hier helfen:

Der Funktionskopf einer Funktion sieht folgendermaßen aus:

Code:
STATUS LNPUBLIC DBDPerformFunction( DBVEC *vec, HDBDSESSION hSession, WORD Function, WORD argc, DWORD *argl, void **argv, HANDLE *rethResult, DWORD *retResultLength )
Dem Parameter "void **argv" kann ich leider überhaupt nicht entnehmen, um was für einen Typ es sich handelt (außer der Tatsache (?), das es ein Zeiger auf einen Zeiger ist).

Im Code findet sich dann das Folgende:
Code:
typedef struct { USHORT ListEntries;
} LIST;

char      *pData;
char      *pFileName;            /* Pointer to database filename         */
DWORD     FileNameLen;           /* Length of packed filename string.    */

...

pData = (char *)argv[0];            /* Get pointer to data   */

...

pData += sizeof(WORD);        /* Step past the datatype word        */
pData += sizeof(LIST);        /*   and step past the list header.   */

FileNameLen = *(WORD *)pData; /* Save length of filename.           */
pData += sizeof(WORD);        /* Step past filename length          */
pFileName = pData;            /* Save pointer to database file name. */

pData = (char *) argv[1]; /* Then the 2nd one should be the key */
                  /*   on which to search;              */
pData += sizeof(WORD);    /* Step past the datatype word        */
pData += sizeof(LIST);    /*   and step past the list header.   */
   
KeyLen = *(WORD *)pData;  /* Save length of key.                */
pData += sizeof(WORD);    /* Step past key length               */
pKey = pData;             /* Save pointer to key.               */

...

Mein Pascal Transfer sieht für den Funktionsaufruf folgendermaßen aus (wobei man durchaus statt "pArgv" auch "TArgv" verwenden könnte, da Pascal ja Strukturen immer als "Zeiger auf" übergibt), wobei ich den Datentyp des Parameters "argv" umgesetzt habe als ein "packed array of pChar", mir aber absolut unklar ist, ob dies so überhaupt korrekt ist):

Delphi-Quellcode:
type
  USHORT = WORD;

  LIST = packed record
    ListEntries: USHORT;
  end;

  pArgv = ^TArgv;
  TArgv = packed array of pChar;

function DBDPerformFunction( vec: pDBVEC; hSession: HDBDSESSION; pFunction: WORD; argc: WORD; argl: pDWORD; argv: pArgv; rethResult: pHANDLE; retResultLength: pDWORD ): STATUS;

var
  pData         : pChar;
  pFileName     : pChar;                                  {* Pointer to database filename              *}
  FileNameLen   : DWORD;                                  {* Length of packed filename string.         *}

begin

  pData := pChar( argv^[ 0 ] );                    {* Get pointer to data   *}

  ...

  pData := pData + System.SizeOf( WORD );            {* Step past the datatype word        *}
  pData := pData + System.SizeOf( LIST );            {* and step past the list header.     *}

  FileNameLen:= WORD( pData );                      {* Save length of filename.           *}
  pData     := pData + System.SizeOf( WORD );       {* Step past filename length          *}
  pFileName := pData;                               {* Save pointer to database file name. *}

  pData := pChar( argv^[ 1 ] );                     {* Then the 2nd one should be the key on which to search; *}
  pData := pData + System.SizeOf( WORD );           {* Step past the datatype word        *}
  pData := pData + System.SizeOf( LIST );          {*   and step past the list header.   *}
  KeyLen:= WORD( pData );                           {* Save length of key.                *}
  pData := pData + System.SizeOf( WORD );           {* Step past key length               *}
  pKey := pData;

  ...

end;

Das Programm stützt nicht ab, aber in den Variablen "FileNameLen", "pFileName", "KeyLen" und "pKey" steht nie was drin, was nicht richtig sein kann.
Ich denke, ich habe einfach den Transfer nicht richtig "hin" bekommen.
Eventuell kann jemand hier helfen ? Wäre toll !

[edit=SirThornberry]Verschidene Quellcode-tags gesetzt - nächstes mal bitte selbst machen. Mfg, SirThornberry[/edit]

Chris.R 22. Feb 2010 14:20

Re: C nach Delphi (Pascal) Konvertierungsproblem
 
Hallo,

Hast du auch die Aufrufkonvention beachtet? C hat meist stdcall.

Außerdem kann man Pointer auch als var Parameter definieren:

Delphi-Quellcode:
function DBDPerformFunction( vec: pDBVEC; hSession: HDBDSESSION; pFunction: WORD; argc: WORD; var argl: DWORD; var argv: pArgv; var rethResult: HANDLE; var retResultLength: DWORD ): STATUS; stdcall;
Ciao Chris

implementation 22. Feb 2010 14:25

Re: C nach Delphi (Pascal) Konvertierungsproblem
 
Nur, wenn auch "__stdcall" vorsteht, sonst ist es automatisch "__cdecl".

MiniMatrix 22. Feb 2010 17:03

Re: C nach Delphi (Pascal) Konvertierungsproblem
 
Ähm, ja. Schon klar.

Aber ich rufe nicht eine Funktion, sondern werde informiert. Also die Funktion "DBDPerformFunction" ist in meiner eigenen DLL. Sie wird aufgerufen und übergibt an mich diese Parameter. Der Fehler scheint im Parameter "argv" zu stecken (Zeiger auf ein Zeigerarray von nullterminierten Strings).

===================
Interface

function DBDPerformFunction( vec: pDBVEC; hSession: HDBDSESSION; pFunction: WORD; argc: WORD; argl: pDWORD; argv: pArgv; rethResult: pHANDLE; retResultLength: pDWORD ): STATUS; stdcall; far;
...
===================

MiniMatrix 22. Feb 2010 17:21

Re: C nach Delphi (Pascal) Konvertierungsproblem
 
Die Verwendung von "cdecl" oder "stdcall" scheint keinen Unterschied zu machen. Es ist aber schon so, dass bei der Beispieldefinition in C die Angabe fehlt, weswegen ich wohl besser bei cdecl bleibe, oder?

Chris.R 22. Feb 2010 19:55

Re: C nach Delphi (Pascal) Konvertierungsproblem
 
Hallo,

hast du schon mal ausprobiert,

Delphi-Quellcode:
argv: pArgv
durch

Delphi-Quellcode:
var argv: pArgv
oder

Delphi-Quellcode:
const argv: pArgv
zu ersetzen?

Ciao Chris

MiniMatrix 2. Mär 2010 12:55

Re: C nach Delphi (Pascal) Konvertierungsproblem
 
So, ich habe das Problem gelöst:

Als erstes habe ich die Definition des Datentyps für den Parameter "argv" umgestellt und erweitert:

Delphi-Quellcode:
type
  ppArgv = ^pArgv;
  pArgv = ^TArgv;
  TArgv = array of pointer;
und den Parameter definiert als:

argv: ppArgv;


Der weitere Zugriff erfolgt nun über:

Delphi-Quellcode:
  pData := pChar( argv^ );                           {* Get pointer to data   *}

  ...

  pData := pData + System.SizeOf( WORD );            {* Step past the datatype word        *}
  pData := pData + System.SizeOf( LIST );            {* and step past the list header.     *}

  FileNameLen:= pWORD( pData )^;                     {* Save length of filename.           *}
  pData     := pData + System.SizeOf( WORD );       {* Step past filename length          *}
  pFileName := pData;                               {* Save pointer to database file name. *}
  pData     := pData + FileNameLen;

  pData := pData + System.SizeOf( WORD );            {* Step past the datatype word        *}
  pData := pData + System.SizeOf( LIST );            {*   and step past the list header.   *}

  KeyLen:= pWORD( pData )^;                         {* Save length of key.                *}
  pData := pData + System.SizeOf( WORD );            {* Step past key length               *}
  pKey := pData;
  pData := pData + KeyLen;
Einziger Wehrmutstropfen ist, dass die Information bezüglich des Array's in C verloren geht. Aber eventuell gibt es ja jemanden, der hierzu noch eine Idee hat.

Fridolin Walther 2. Mär 2010 15:00

Re: C nach Delphi (Pascal) Konvertierungsproblem
 
Obligatorische Frage: Welche Delphi Version benutzt Du?


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:28 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