Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Abbildung einer C-Funktion nach Delphi (https://www.delphipraxis.net/144861-abbildung-einer-c-funktion-nach-delphi.html)

R2009 18. Dez 2009 10:24


Abbildung einer C-Funktion nach Delphi
 
Hi,

folgendes Problem. Ich würde gerne diese Funktion nach Delphi abbilden:

static int callback(void *NotUsed, int argc, char **argv, char **azColName)

Mein Ansatz:
Delphi-Quellcode:
   Function callback(n:pointer;argc:integer,argv:pointer;azcolname:pointer);
Ich habe keine Ahnung was die ** bedeuten und habs auch im Internet nicht gefunden.
Vermutlich ist das ein Pointer auf einen Pointer oder so etwas.
Kann mir jemand helfen die gesamte Funktion abzubilden?

Grüsse
Rainer

Mithrandir 18. Dez 2009 10:42

Re: Abbildung einer C-Funktion nach Delphi
 
** ist, wie du schon richtig vermutet hast, ein Doppelzeiger.

static int callback(void *NotUsed, int argc, char **argv, char **azColName)

Delphi-Quellcode:
Function CallBack( NotUsed: Pointer; argc: Integer; var argv: PAnsiChar; var azColName: PAnsiChar ): Integer
Das wäre so in etwa mein Vorschlag für eine 1:1 Übersetzung. Ob das im Kontext allerdings Sinn ergibt, dass ist die zweite Frage...

Denn ich vermute einfach mal, dass in argv und azColName Zeichenketten stehen, oder?

R2009 18. Dez 2009 10:47

Re: Abbildung einer C-Funktion nach Delphi
 
Hi Daniel,
ja sieht so aus.
Ich habe versucht die Callback Funktion des SQLite Beispiels so zu übersetzen, dass ich sie in Delphi nutzen kann.

Der Code:

Delphi-Quellcode:
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
  int i;
  for(i=0; i<argc; i++){
    printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
  }
  printf("\n");
  return 0;
}

int main(int argc, char **argv){
  sqlite3 *db;
  char *zErrMsg = 0;
  int rc;

  if( argc!=3 ){
    fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
    exit(1);
  }
  rc = sqlite3_open(argv[1], &db);
  if( rc ){
    fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
    sqlite3_close(db);
    exit(1);
  }
  rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
  if( rc!=SQLITE_OK ){
    fprintf(stderr, "SQL error: %s\n", zErrMsg);
    sqlite3_free(zErrMsg);
  }
  sqlite3_close(db);
  return 0;
}
Ziel soll sein, dass der eigentliche Aufruf in eine DLL geschrieben wird, die Callback Funktion jedoch in Delphi bleibt.
Das Ergebnis wäre eine ganz einfache Schnittstelle zu SQlite, die nur auf SQL Befehlen basiert.

Vielen Dank und Grüsse
Rainer

gammatester 18. Dez 2009 12:14

Re: Abbildung einer C-Funktion nach Delphi
 
**argv wird wohl besser übersetzt mit const array of pchar oder const array of pansichar, mit ziemlicher Sicherheit bezeichnet **argv ein Array. Standardmäßig wird argc/argv doch benutzt, um die Anzahl der Kdo-Zeilenparameter und das Array der eigentlichen Parameter zu bezeichnen.

Gruß Gammatester

R2009 27. Dez 2009 08:39

Re: Abbildung einer C-Funktion nach Delphi
 
Hi,
hab das:
Code:
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
mit:
Delphi-Quellcode:
Function zielfunktion1( NotUsed: Pointer; argc: Integer; const argv:array of pchar; const azcolname:array of pchar ): Integer;cdecl;
übersetzt.
Funktioniert für die ersten 2 Parameter. Im dritten steht nur Mist drin.
Bin fast am verzweifeln. Gibts hier irgendjemand der mir auf die Sprünge helfen kann?
Ziefunktion1 ist im übrigen die Callbackfunktion von Sqlite3_exec.
Noch ein Hinweis: ich kann die Struktur der aufrufenden Funktion nicht ändern.

Grüsse
rainer

R2009 27. Dez 2009 11:01

Re: Abbildung einer C-Funktion nach Delphi
 
Hi,

gibts hier keinen C Profi der mir auf die Sprünge helfen kann?

Grüsse
Rainer

Niko 27. Dez 2009 12:07

Re: Abbildung einer C-Funktion nach Delphi
 
Hi,

Code:
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
char** ist ein Zeiger auf einen Zeiger auf char oder, was in C das gleiche ist, ein Array von Zeichenarrays (= nullterminierten Strings).

In Delphi muss das dann so aussehen:
Delphi-Quellcode:
type
  PPCharArray = ^PCharArray;
  PCharArray = Array[0..0] of PChar;

Function zielfunktion1( NotUsed: Pointer; argc: Integer; argv: PPCharArray; azcolname: PPCharArray): Integer; cdecl;
Korrekt wäre auch:
Delphi-Quellcode:
type
  PPChar = ^PChar;

Function zielfunktion1( NotUsed: Pointer; argc: Integer; argv: PPChar; azcolname: PPChar): Integer; cdecl;
Aber dann kannst du nur über Zeigerarithmetik auf das Array zugreifen und nicht über Indizes.

R2009 27. Dez 2009 12:28

Re: Abbildung einer C-Funktion nach Delphi
 
Hi Nico,

vielen vielen dank, hat funktioniert. Ich bin fast verzweifelt an diesem problem.
Noch eine kleine Frage:
Delphi-Quellcode:
type
  PPCharArray = ^PCharArray;
  PCharArray = Array[0..10] of PChar;
Bei der Dimension des Arrays muss ich doch von vorne herein eine obere Grenze angeben oder?
Mit Array[0..0] kann ich nur auf a[0] zugreifen.

Grüsse
Rainer

Niko 27. Dez 2009 13:24

Re: Abbildung einer C-Funktion nach Delphi
 
Eine obere Grenze anzugeben ist eine Möglichkeit. Da du die wirkliche Größe zur Übersetzungszeit aber sowieso nicht kennst, kannst du auch die Bereichsprüfung des Compilers für den entsprechenden Abschnitt ausschalten (mit {$R-}, ist zumindest bei Delphi 2006 auch die Vorgabe). Letzteres halte ich für die sauberere Variante.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:00 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz