Callbackfunktion aus DLL herauslösen!



  • Hi,
    Problem:
    Ich habe eine Funktion deschrieben, die Parameter an Sqlite weitergibt.
    Unter anderem auch eine Callbackfunktion. Jetzt möchte ich die Callbackroutine aus der DLL raus haben.
    Die Callbackroutine soll in einem Delphi Programm stehen.
    das Problem ist, dass ich die Callbackadresse irgendie weitergeben muss!
    Ich hab einen void* an QtTestDll_Sqlite angehängt.

    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; 
    } 
    
    extern "C" __declspec( dllexport ) void QtTestDll_Sqlite(char* Database,char* SQL_string, void* ptr) 
    { 
        sqlite3 *db; 
        char *zErrMsg = 0; 
        int rc; 
        TCHAR Inhalt[101]; 
    
        rc = sqlite3_open(Database, &db); 
        if( rc ){ 
          //Fehlermeldung ausgeben 
          //fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); 
          sqlite3_close(db); 
          exit(1); 
        } 
        wtoci(Inhalt,SQL_string,sizeof(SQL_string)); 
        rc = sqlite3_exec(db,SQL_string,ptr, NULL, &zErrMsg);<--------hier meckert Compiler wegen ptr 
        if( rc!=SQLITE_OK ){ 
          //fprintf(stderr, "SQL error: %s\n", zErrMsg); 
          sqlite3_free(zErrMsg); 
        } 
        sqlite3_close(db); 
    
       // 
    }
    

    Compiler meckert:
    rtest.cpp:77: error: invalid conversion from 'void*' to 'int ()(void, int, char**, char**)'
    rtest.cpp:77: error: initializing argument 3 of 'int sqlite3_exec(sqlite3*, const char*, int ()(void, int, char**, char**), void*, char**)'

    Ich bin nicht sicher ob ich im richtigen Forum gelandet bin:
    Grüsse
    Rainer



  • Ohne jetzt genau zu wissen was du da machst, probier mal statt nem void Pointer einen Funktionspointer zu nehmen und in Zeile 10 das hier hinzuschreiben:

    extern "C" __declspec( dllexport ) void QtTestDll_Sqlite(char* Database,char* SQL_string, int (*ptr)(void*, int, char**, char**))
    


  • r2009 schrieb:

    Compiler meckert:
    rtest.cpp:77: error: invalid conversion from 'void*' to 'int ()(void, int, char**, char**)'

    wenn das c++ ist (wie's aussieht), dann versuch mal die callback-funktion extern "C" zu machen und dann einfach nach 'void*' casten. in C braucht man übrigens keinen cast, sondern kann die adresse einer funktion direkt einem void* zuweisen. in C++ sind void* und function-pointer ziemlich kaputt.
    btw, das passend forum für deine frage wäre wohl 'winapi'.
    🙂



  • Hi,
    hat funktioniert, so wie du es vorgeschlagen hattest.
    Vielen Dank

    PS: mit void* ging das überhaupt nicht.

    Ich hasse C und C++ mittlerweile.
    Wie gut geht das doch alles mit Delphi.
    (Aber ich muss leider mein Chef ist C++ Freak)

    Grüsse
    rainer



  • r2009 schrieb:

    Ich hasse C und C++ mittlerweile.

    willkommen im club *fg*, aber versuch mal deinen C++-hass nicht auf C zu projizieren. C++ ist nicht C. C ist eine coole und entspannte programmiersprache, zwar sehr spartanisch, aber für viele zwecke genau das richtige. unter C existiert dein problem übrigens garnicht erst.

    r2009 schrieb:

    Wie gut geht das doch alles mit Delphi.
    (Aber ich muss leider mein Chef ist C++ Freak)

    dann verweise ihn doch auf yossi kreinis page, oder fefes C++ slides *fg*. aber da ihr scheinbar windows-usermode-progrämmchen baut, werded ihr mit C wohl auch nicht glücklich. schaut euch doch mal .NET an. der C#-chefdesigner ist übrigens der gleiche, der delphi und turbo-pascal entwickelt hat.
    🙂



  • Hi,
    wir bauen Parametriertools für die Stromzähler und Rundsteuertechnik (Win32).
    Des weiteren habe ich C und Assembler Programme für ATmega 32 16 88 geschrieben.
    Dort ist C aber geradezu lächerlich einfach. Sobald ich aber mit Typecasts und Pointer zu tun habe krieg ich die Krise.

    Unsere ganzen Tools sind Delphi basiert. Da wir aber damit, von der manpower, als auch von der Preispolitik (eine Entwicklerlizenz koste 1200€) her an unsere Grenzen stossen wollen wir versuchen einen Teil des Codes nach C oder C++ und da in DLL's zu exportieren.
    C# wäre auch noch eine Möglichkeit aber alle Gerüchte besagen, dass das von Delphi aus nicht geht.

    Im übrigen ist mein Problem gelöst! Ich werde meine DLL in Kürze hier einstellen.

    Grüsse
    Rainer



  • Hi,
    additiv noch ein kleines Problem:(Wieder typecast)

    extern "C" __declspec( dllexport )  char* QtTestDll_Sqlite(char* Database,char* SQL_string, int (*ptr)(void*, int, char**, char**))
    .
    .
    rc = sqlite3_open(Database, &db);
    

    per Definition ist:
    int sqlite3_open(
    const char *filename, /* Database filename (UTF-8) */
    sqlite3 **ppDb /* OUT: SQLite db handle */

    Database wird nicht übergeben.
    Wenn ich direkt:
    rc = sqlite3_open("D:\Test.db", &db);
    schreibe geht das.

    Hilft mir bitte nocheinmal jemand?

    Grüsse
    Rainer



  • sqlite3 *db = malloc(sizeof(sqlite3));
    rc = sqlite3_open("D:\Test.db", &db);
    //tu was sinnvolles mit db
    free(db);
    

    😕

    Ich glaube ich habe dein Problem nicht verstanden, was willst du denn casten?



  • Hi,

    Database wird einfach nicht an sqlite3_open weitergeben und ich weiss nicht warum.
    Schreibe ich in sqlite_open direkt "D:\Test.db" dann funktioniert alles.
    Ansonsten öffnet er die Datenbank nicht.

    Grüsse
    Rainer



  • ^^mach doch mal 'ne debug-ausgabe in deiner QtTestDll_Sqlite-funktion, ob der string 'char *Database' auch tatsächlich was gültiges beinhaltet (mit 'ner messagebox oder so). und falls du sonderzeichen im namen verwendest, müssteste die noch nach utf-8 konvertieren (im bereich 0x00...0x7f sind ascii- und utf8-zeichen identisch). wenn bei der debug-ausgabe nur ein zeichen sehen solltest, dann kanns daran liegen, dass die client-anwendung einen 'wchar_t' einspeisst. windoofs arbeitet dummerweise native mit utf-16.

    nwp2 schrieb:

    sqlite3 *db = malloc(sizeof(sqlite3));
    

    ach nö, malloc für eine temporäre struct? leg sie doch direkt an: sqlite3 db;, geht schneller und 'free' brauchste dann auch nicht.
    🙂



  • ;fricky schrieb:

    ach nö, malloc für eine temporäre struct?

    Du hast es schon gesagt. Temporär. Zeitlich begrenzt. Man baut sich die Struktur wenn man sie braucht und wird sie danach wieder los, kein Grund sie von Anfang bin Ende bereit zu halten. Malloc ist genau für vorübergehende Strukturen da, direkt definieren ist nur für dauerhaft benötigte Strukturen sinnvoll.

    Aber ich glaube in diesem Punkt werden wir uns wohl nie einig 😉



  • nwp2 schrieb:

    Malloc ist genau für vorübergehende Strukturen da, direkt definieren ist nur für dauerhaft benötigte Strukturen sinnvoll.

    Magst du nicht mal nachprüfen, wieviel teurer so ein kleines malloc() ist, verglichen damit, eine Instanz eines kleinen Typs auf den Stack zu legen?
    🙂



  • ;fricky schrieb:

    in C braucht man übrigens keinen cast, sondern kann die adresse einer funktion direkt einem void* zuweisen. in C++ sind void* und function-pointer ziemlich kaputt.
    btw, das passend forum für deine frage wäre wohl 'winapi'.
    🙂

    Das kann man in C++ auch. Nur andersherum geht es nicht. Wenn Du darüber nachdenkst, dann kommst Du vielleicht auch drauf, warum das sinnvoll ist.

    r2009 schrieb:

    Compiler meckert:
    rtest.cpp:77: error: invalid conversion from 'void*' to 'int ()(void, int, char**, char**)'

    Wie gesagt: Andersherum... 🙂



  • Tachyon schrieb:

    Das kann man in C++ auch. Nur andersherum geht es nicht. Wenn Du darüber nachdenkst, dann kommst Du vielleicht auch drauf, warum das sinnvoll ist.

    ich hab' sowieso mist erzählt. zuweisungen von function pointer an data pointer und umgekehrt geht beides nicht, erzeugt zumindest warnings, ob mit cast oder ohne: http://www.devx.com/tips/Tip/12890
    🙂



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum ANSI C in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


Anmelden zum Antworten