Problem mit SQLite und der TForm Klasse



  • Hallo,

    habe heute versucht SQLite in meine Anwendung zu integrieren, dazu habe ich meinem Projekt die sqlite3.c hinzugefügt und in meiner Test cpp Datei den Include gesetzt: #include "sqlite3.h"

    Der Aufruf des SQL Querys scheint auch zu funktionieren nur happert es bei der Callback Funktion.

    Hier Zeile 32-38 meines Codes:

    rc = sqlite3_exec(
                db,
                sql.c_str(),
                callback,
                0,
                &zERRmsg
            );
    

    Definiere ich die Funktion "callback" außerhalb der TForm Klasse funktioniert es wohl, definiere ich sie innerhalb der Klasse (um aus der Callback-Funktion heraus auf das Form zugreifen zu können), bekomme ich folgende Fehlermeldung:

    [BCC32 Fehler] Unit1.cpp(38): E2034 Konvertierung von 'int (* (_closure )(void *,int,char * *,char * *))(void *,int,char * *,char * *)' nach 'int (*)(void *,int,char * *,char * *)' nicht möglich
    [BCC32 Fehler] Unit1.cpp(38): E2342 Keine Übereinstimmung des Typs beim Parameter 'callback' ('int (*)(void *,int,char * *,char * *)' erwartet, 'void' erhalten)
    

    Die Definition sieht wie folgt aus:

    int callback(void* unused, int colCount, char** colValue, char** colName);
    

    Was mache ich da nur falsch?

    Vielen Dank für eure Hilfe!



  • Du kannst nur freie Funktionen oder statische Methoden übergeben, keine Objektmethoden.

    Außerdem frage ich mich, wie sinnvoll es ist, sich mit dem Low-level-API einer Datenbank herumzuschlagen, wenn man schon ein RAD-Tool wie C++Builder verwendet? Ich würde lieber einen dbExpress-Treiber für SQLite (1, 2) oder so etwas wie ZEOS oder AnyDAC verwenden.



  • Hallo

    Wie du schon selber festgestellt hast, verlangt sqlite3_exec eine statische Funktion, und du kannst nicht eine Membermethode übergeben. Daran kannst du nichts ändern.
    Um denoch innerhalb der Callback-Funktion auf dein Form zugreifen zu können, hat die sqlite3_exec-Funktion neben dem Zeiger auf die Callback-Funktion noch einen weiteren Parameter, der vermutlich "Data" genannt wurde und an dem du aktuell nur 0 übergibst. Dort kannst du einen Zeiger auf ein beliebiges Datenkonstrukt übergeben, das dir dann in der Callback-Funktion wieder mitgegeben wird : in dem von dir als "unused" bezeichneten Parameter. In deinem Fall übergibst du also den Zeiger auf dein Form als Data :

    rc = sqlite3_exec(
                db,
                sql.c_str(),
                callback,
                this, // Wenn sqlite3_exe aus einer Membermethode des Forms heraus aufgerufen wird
                &zERRmsg
            );
    ...
    int callback(void* data, int colCount, char** colValue, char** colName)
    {
      TForm1* Form = static_cast<TForm1*>(data); // Zeiger wieder als TForm1 ansprechen
    }
    

    Das ist ein allgemeines Prinzip bei Callback-Funktionen und findet sich z.B. auch oft in der WinAPI wieder.

    /Edit : Der Hinweis auf ein VCL-unterstützendes Interface von audacia ist aber berechtigt. Spart viel Arbeit.

    bis bald
    akari



  • Danke für die schnellen und vor allem konstruktiven Antworten audacia und akari.

    @ audacia : Ich schlage mich damit rum weil ich bislang einfach keine Ahnung habe dass es anders geht, habe bereits angefangen die von dir genannten Links durchzugehen und werd versuchen es damit sauber zu lösen. Vielen Dank!

    @ akari : Danke für die Erklärung, das wird jetzt wohl zunächst meine "Fallback" Lösung wenn ich mit den von audacia genannten Sachen gar nicht klarkommen sollte. Ist jedenfalls hilfreich zu wissen wieso und warum es so ist, dickes Danke!

    Nochmal allgemein zum Thema, es wäre also auf jeden Fall sinnvoller einen dbExpress Treiber zu verwenden als das was ich jetzt vorgehabt hätte?!



  • Hallo

    Mit den genannten VCL-kompatiblen Paketen kannst du dann auch gleich die ganzen datensensitiven Komponenten wie T...Query und TDBGrid verwenden, was dir wie gesagt viel Arbeit erspart, da du dann die immer wiederkehrenden Standardinteraktionen für Datenbank-Anwendungen nicht selber schreiben must.

    bis bald
    akari


Anmelden zum Antworten