Kann mir jemand diese Funktion erklären?

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Benutzeravatar
Bebu
Beiträge: 562
Registriert: Mi Okt 21, 2009 6:19 pm
Wohnort: In der Nähe von Salzburg - Bin aber kein Österreicher!

Kann mir jemand diese Funktion erklären?

Beitrag von Bebu » Sa Dez 12, 2009 9:28 pm

Nachdem ich mich gerade in das Thema SQLite hineinarbeite bin ich auf die sqlite3_exec Funktion gestoßen. Diese Funktion ermöglicht es, ein SQL Kommando mit nur einem Befehl auszuführen, wenn die Verbindung erstmal steht.
Die Funktion wird mit folgenden Argument aufgerufen:

Code: Alles auswählen

int sqlite3_exec(
  sqlite3*,                                                /* Datenbankhandle */
  const char *sql,                                     /* SQL Kommando */
  int (*callback)(void*,int,char**,char**),  /* Callback Funktion */
  void *,                                                  /* 1st argument to callback */
  char **errmsg                                        /* Hierhin wird eine Fehlermeldung geschrieben */
);
Der schwierige Teil für mich ist die Callbackfunktion. Sie dient dazu, die Daten aus der Datenbank zu holen, wenn ein Kommando ausgeführt wird, das ein Ergebnis zurückliefert.
Vier Sachen sind mir nicht in der folgenden Funktion wenig oder gar nicht klar:
1. Was und wozu dient das "void *show_col"? Was ist das für ein Pointertyp und worauf zeigt der?
2. Wozu dient die Typumwandlung des void-Pointers in einen bool-Pointer?
3. Was genau geschieht bei dieser Anweisung: (argv ? argv : "")? Ich habe schon herausgefunden, das es sich um einen Bedingunsoperator handelt, der je nach dem, ob die Bedingung erfüllt ist, entweder den einen oder den anderen Wert zuweist.
4. Wozu dient der Doppelstern wie z. B. char **argv?
Hier die fragliche Funktion:

Code: Alles auswählen

int callback(void *show_col, int argc, char **argv, char **column)
{
  bool *show_column(static_cast<bool *>(show_col));

  for (int i = 0; i != argc; ++i) {
    if (*show_column)
      cout << column[i] << ": ";
    cout << (argv[i] ? argv[i] : "") << '\n';
  }
  cout << endl;

  return 0;
}
Wer immer nach dem Unerreichbaren jagt, der wird irgendwann auf die Schnauze fallen!

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Kann mir jemand diese Funktion erklären?

Beitrag von Xin » Sa Dez 12, 2009 9:42 pm

Bebu hat geschrieben:1. Was und wozu dient das "void *show_col"? Was ist das für ein Pointertyp und worauf zeigt der?
Da scheint sich SQLite auch nicht ganz festlegen zu wollen, das wirst Du vermutlich nur der Dokumentation von SQLite oder Kerli entnehmen können. ^^
void * heißt soviel wie 'Zeiger auf irgendwas'.
Bebu hat geschrieben:2. Wozu dient die Typumwandlung des void-Pointers in einen bool-Pointer?
Dass das 'irgendwas' bei diesem Callback wohl ein 'bool' ist, also 'show_col' ein Zeiger auf ein Bool. Wenn das ein C-Interface ist, dann ist dabei zu sagen, dass C keine bool kennt.
Bebu hat geschrieben:3. Was genau geschieht bei dieser Anweisung: (argv ? argv : "")? Ich habe schon herausgefunden, das es sich um einen Bedingunsoperator handelt, der je nach dem, ob die Bedingung erfüllt ist, entweder den einen oder den anderen Wert zuweist.

Genau das macht das.

Die Anweisung

Code: Alles auswählen

cout << (argv[i] ? argv[i] : "") << '\n';
entspricht

Code: Alles auswählen

if( argv[i] ) cout << argv[i] << '\n';
else      cout << "" << '\n';
Da wollte nur einer weniger tippen.
Bebu hat geschrieben:4. Wozu dient der Doppelstern wie z. B. char **argv?
Der Doppelstern sind zwei Sterne. Ein Stern heißt 'Pointer auf ...'. Zwei Sterne heißen 'Pointer auf Pointer auf ...'
In Deinem Fall Pointer auf Pointer auf char.
(char *) ist ein Zeiger auf einen Buchstaben. Häufig auf den ersten Buchstaben von einem Array von Buchstaben - also einem Text.
((char *)*) ist ein Zeiger auf einen ((Zeiger auf einen Buchstaben) == Text). Auch in dem Fall ist das wohl ein Zeiger auf den ersten Text. Also ist (char **) ein Array von Texten - vermutlich dem Inhalt der einzelnen Spalten. ^^
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Kann mir jemand diese Funktion erklären?

Beitrag von Kerli » So Dez 13, 2009 11:08 am

Xin hat geschrieben:Wenn das ein C-Interface ist, dann ist dabei zu sagen, dass C keine bool kennt.
Genau so wenig wie static_cast, cout, etc. ;)
Bebu hat geschrieben:1. Was und wozu dient das "void *show_col"? Was ist das für ein Pointertyp und worauf zeigt der?
Das ist einfach nur ein benutzerdefinierter Parameter. Dh. wenn du deiner Callbackfunktion immer einen bestimmten Wert übergeben möchtest kannst du diesen Parameter dazu verwenden.
Bebu hat geschrieben:2. Wozu dient die Typumwandlung des void-Pointers in einen bool-Pointer?
Das ist keine Umwandlung in einen bool-Pointer, sondern zu einem bool. Dieses Argument der Callbackfunktion dient ja dazu dass man dieser Funktion ein beliebiges Argument übergeben kann. Damit man sich nicht auf einen bestimmten Typ festlegen muss gibt man dafür meistens einen Zeiger auf void an. Den kann man dann durch casten als einen beliebigen anderen Typ interpretieren. Wenn man mehrere Werte übergeben möchte kann man ihn zum Beispiel als Zeiger auf irgendeine Struktur interpretieren, und in diesem Fall wenn es sich nur um ein einziges Argument handelt auch gleich zu dessen Datentyp. Ein void Zeiger ist ja auf einer 32-Bit Plattform nichts anderes als ein 32-Bit Wert.

Bei dem Code von dir da gibt derjenige der ihn verfasst hat damit zum Beispiel an, ob auch der Spaltenname ausgegeben werden sollte.

edit: Hier ist noch der Link zur Einführung auf der SQLite Homepage. Da wird auch sqlite3_exec verwendet...
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Benutzeravatar
Bebu
Beiträge: 562
Registriert: Mi Okt 21, 2009 6:19 pm
Wohnort: In der Nähe von Salzburg - Bin aber kein Österreicher!

Re: Kann mir jemand diese Funktion erklären?

Beitrag von Bebu » So Dez 13, 2009 9:43 pm

Besten Dank, jetzt bin ich schon wieder ein gutes Stück weiter. Den Code dazu zu bringen, seinen Zweck zu erfüllen, ist einfach: Copy and Paste. Aber zu verstehen, was wirklich passiert ist wohl nötig, um eine gute Erklärung dazu zu schreiben. ;) Wieder ein Stück für das SQLite Tutorial.
Wer immer nach dem Unerreichbaren jagt, der wird irgendwann auf die Schnauze fallen!

Antworten