Mysql embedded Server von VCC 7.0 läuft nicht an



  • Hi,
    bin am verzweifeln, ich versuche mit folgendem Code, einen embedded Server von Mysql zu starten:

    #include "stdafx.h"
    #include "mysql.h"
    #include "stdarg.h"
    #include "stdio.h"
    #include "stdlib.h"
    const char *server_groups[] = {"test_libmysql_SERVER", "embedded", "server", NULL};
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    	//mysql_server_init(NULL, NULL, NULL);
    	mysql_server_init(argc, argv, (char **)server_groups);
    
    	return 0;
    }
    

    Hab die libmysqld.dll über libmysqld.lib erfolgreich eingebunden, Programm wird ohne Fehler kompiliert, steigt aber während der mysql_server_init einfach aus (Konsolenfenster geht zu). Auch die auskommentierte Funktion liefert dasselbe Ergebnis 😡

    Kann mir da helfen, ich bin mit meinem Latein (schon wieder) am Ende

    Gruß Squeegee



  • Dafür gibt es Code auf der Seite von www.mysql.de

    Kann mich aber erinnern das der emb-Server eine andere BIB verwendet.



  • Das ist genau der Code von www.mysql.de, nur der ganze Rest weggelassen.
    Aber auch den Code 1:1 genommen erzeugt denselben Fehler... Oder besser denselben Ausstieg 😕

    Was meinst du mit BIB? Bibliothek? Wenn ja, welche meinst du? Ich kenn und hab nur die



  • hm...

    Suspekt.

    Die libmysqld sollte schon stimmen.
    Die normale mysql-Api steht in der libmysql (ohne d).

    Passen die import-lib und die dll Versionsmäßig zusammen?



  • Hab mir das angesehen. War etwas verwirrt über das d weil meine lib dann immer ein debug ist.

    Dein Fenster geht zu weil du nichts damit machst. Was sollte auch passieren. Du initialisierst den Server und dein Code ist zu ende.
    Weiters fehlt dir z.B. mysql_server_end();
    Sieht dir das beispiel nochmals an. Es sendet 2 SQL-Querys db_do_query(one, "show table status", E_fail);
    db_do_query(two, "show databases", E_fail); und beendet sich ebenfalls.

    Was willst du also erreichen?
    Willst du dein Programm als Serverdaemon verwenden bist du mit EMP-Server falsch.
    Dafür hat MySQL einen eingenen.



  • Hi,
    laut
    http://dev.mysql.com/doc/mysql/en/libmysqld-compiling.html
    ist die libmysqld keine Debugversion sondern die Version von libmysql, die der embedded Server braucht.
    Das Programm beendet sich auch nicht einfach, sondern es fliegt definitiv wärend des inits raus, weil nachfolgende Anweisungen nicht ausgeführt werden. Ich hatte ursprünglich danach noch einen Text ausgegeben und das Progi in ne while(1); Schleife geschickt, damit sich das Fenster nicht schließt. Und beim debuggen schmeißt mich ja auch der Debugger von Visual immer raus...
    Weitere Befehle fehlen schlicht deswegen, weil ich sie zur Übersicht rausgelöscht habe.
    Schon eher könnte es das Problem mit verschiedenen Versionen der lib und der dll sein... Die lib ist ja bei der noinstall-Windows Version von mysql schon dabei, die dll soll man sich selber machen.
    Hat vielleicht jemand diese beiden Dateien (libmysqld.lib und libmysqld.dll) in getesteter Version und kann sie mir zukommen lassen?

    Gruß Squeegee



  • was steht in deiner my.cnf?
    kann es sein das er datenfiles oder so nicht findet.

    http://dev.mysql.com/doc/mysql/de/mysql-server-init.html



  • Squeegee schrieb:

    Die lib ist ja bei der noinstall-Windows Version von mysql schon dabei, die dll soll man sich selber machen.

    ??
    eher umgekehrt, z. B. kann der Borland Compiler oder auch der MinGW mit
    der libmyslq(d).lib nix anfangen, da die nur für's VS da ist.
    In diesem Fall gibts für Borland "implib.exe" fürn gcc das "dlltool.exe" zum
    Erstellen der Importlibrary aus der libmysql(d).dll

    Für's VS gibts glaub ich "lib.exe", aber keine Ahnung, wie man das verwendet.
    Aber wie gesagt, die lib die dabei ist sollte schon funktionieren.

    Squeegee schrieb:

    Hat vielleicht jemand diese beiden Dateien (libmysqld.lib und libmysqld.dll) in getesteter Version und kann sie mir zukommen lassen?

    Lad dir doch einfach MySQL neu runter und verwende dann die dll + lib von der
    grade runtergeladenen.
    Dann passen die in jedem Fall zusammen.

    Was auch noch sein kann:
    Existiert evtl. das Verzeichnis, in dem der embedded Server seine Dateien
    ablegt nicht? Dann steigt das server_init auch aus.
    Das Verzeichnis ist zu finden unter "datadir=..." in der config
    (entweder bei den serverargs oder in der config-Datei in der entsprechenden Gruppe)

    @Unix-Tom:
    oder hast du das mit "datenfiules" gemeint?



  • Ja hab ich. War nur ein Tipfehler.
    Datenfiles sind für mich alles was der Server braucht.



  • Hi,
    hmmm, my.ini...
    Frage: Ich hab nur die, die beim Windows-Installer automatisch mitinstalliert wurde und die liegt in meinem Installationsverzeichnis.
    Findet die der Server die an der Stelle?



  • Hi,
    ich bins schon wieder!
    Hatte wohl tatsächlich einen Versionskonflikt zwischen meiner dll und meiner lib...
    Bin zugegebenermaßen nie auf die Idee gekommen, dass es die DLL auch fertig gibt.
    Bei der Version mit dem Installationstool für Windows ist sie nämlich nicht dabei, nur bei der noinstall-Version. 🙂
    Irgendwie stell ich mich wohl etwas an, aber ich hab jetzt noch ein Problemchen, nämlich folgende Fehlermeldung:

    ...Can't find messagefile '*C:\mysql\share\english\errmsg.sys'

    Den Pfad geb ich ja in der my.ini ab, aber:
    Kann ich den Pfad, wo die my.ini liegen soll, anpassen, bzw. warum findet er meine my.ini im windows-Verzeichnis nicht, da soll sie doch eigentlich laut Referenzhandbuch hin?
    Slash oder Backslash, laut Referenzhandbuch Slash in der Fehlermeldung aber Backslash?

    Dann hab jetzt einfach einen Dateipfad so angelegt, wie es in der Fehlermeldung verlangt wird und das File dorthin kopiert. Jetzt steigt er schon wieder kommentarlos aus 😡

    Danke für eure Geduld mit mir

    Gruß Squeegee



  • ich geb dir jetzt einfach mal meine Config für den mysql_embedded_server:

    static char *server_args[] = {
      "myNiceProgram", // program
      "--defaults-extra-file=my.ini"
    };
    
    static char *server_groups[] = {
      "embedded",
      "server",
      "myNiceProgram_settings",
      (char *)NULL
    };
    
    mysql_server_init(sizeof(server_args) / sizeof(char *),  server_args, server_groups);
    

    das "--defaults-extra-file=my.ini" gibt ihm an, dass er die my.ini im selben Verzeichnis wie die exe suchen soll (bzw. vermutlich auch alle Verzeichniss der
    path-Umgebungsvariablen)

    Und hier noch die my.ini selber:

    [embedded]
    basedir="."
    datadir="./data"
    default-character-set=latin1
    default-storage-engine=INNODB
    language="."
    

    die errmsg.sys sucht er dort, wo's ihm mit "language=" gezeigt wird.
    In diesem Fall also im selben Verzeichnis wie die exe Datei.
    => einfach mal im mysql Installationsverzeichnis danach suchen und rüberkopiern



  • Hi,

    hab dein Skript ausgetestet, erzeugt wieder die Fehlermeldung, dass er die errmsg.sys nicht findet, wenn ich diese im gleichen Verzeichnis wie die exe habe.
    Dort hab ich auch die my.ini mit deinen Änderungen.
    Kopiere ich die errmsg.sys wieder nach C:\mysql\share\english\, steigt er wieder kommentarlos aus. 😡
    Kann es sein, dass er die my.ini einfach nicht findet (warum auch immer) und dann mit Standarwerten zu starten versucht, was logischerweise nicht funktioniert? 😕

    Falls jemand noch ne Idee hat, bin für alles zu haben. Ich werds jetzt mal auf nem anderen Rechner testen, auf dem überhaupt kein MySQL installiert ist, ob da dasselbe Problem besteht.

    Gruß Squeegee



  • mal eine blöde Frage:
    Was ist eigentlich VCC 7.0?
    Hab bisher nur schnell drübergeschaut und bin von Visual Studio
    ausgegangen.
    Google bringt für "VCC 7.0" nur wirres Zeug.

    Egal.

    Habs jetzt grad mal ausprobiert mit Dev-C++ (eigentlich wxDev-C++, aber sollte
    eigentlich egal sein).
    Ausserdem dürfte es auch in anderen Compilern ähnlich funktioniern,
    der Unterschied liegt in der Importlib für die libmysqld.dll.
    (
    Erstellung der importlib für gcc: siehe hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-100731-and-highlight-is-.html#719609

    für Borland Compiler:
    http://www.c-plusplus.net/forum/viewtopic.php?t=88356

    für Visual Studio:
    die libmysqld.lib wird mit mysql schon mitgeliefert
    )

    #include <iostream>
    #include <stdexcept>
    #include <winsock.h>
    
    #include "../include/mysql/mysql.h"
    
    int run();
    
    int main()
    {
        try
        {
        run();      
        std::cin.get();
        return 0;
        }
    
        catch (std::exception & Ex)
        {
        std::cerr<<Ex.what()<<std::endl;
        std::cin.get();
        return 1;
        }
    
        catch (...)
        {
        std::cerr<<"unknown exception detected"<<std::endl;
        std::cin.get();
        return 2;      
        }
    }
    
    int run()
    {
    
    static char *server_args[] = 
    {
    "myNiceProgram", // program
    "--defaults-extra-file=my.ini"
    };
    
    static char *server_groups[] = {
    "embedded",
    "server",
    "myNiceProgram_settings",
    (char *)NULL
    };
    
    // Server initialisieren
    mysql_server_init(sizeof(server_args) / sizeof(char *),  server_args, server_groups);
    
    // Datenbankhandle initialisieren
    
    MYSQL *  m_dbHandle = mysql_init(NULL);
    
    // Verbindung herstellen
    mysql_real_connect(m_dbHandle, "", "", "", "", 0, NULL, 0);
    
        // Fehler abfangen
    	if (mysql_errno(m_dbHandle) > 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    int errorNumber;
    std::string query = "create database if not exists myDatabase";
    errorNumber = mysql_real_query(m_dbHandle, query.c_str(), query.length());
    
        // Fehler abfangen
    	if (errorNumber > 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    query = "use myDatabase";
    errorNumber = mysql_real_query(m_dbHandle, query.c_str(), query.length());
    
        // Fehler abfangen
    	if (errorNumber > 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    query = "create table if not exists myTable (id int not null primary key auto_increment, name varchar(255))";	
    errorNumber = mysql_real_query(m_dbHandle, query.c_str(), query.length());
    
        // Fehler abfangen
    	if (errorNumber > 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    query = "insert into myTable (name) values('Huaba'), ('Meier')";
    errorNumber = mysql_real_query(m_dbHandle, query.c_str(), query.length());
    
        // Fehler abfangen
    	if (errorNumber > 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    query = "select name from myTable";
    errorNumber = mysql_real_query(m_dbHandle, query.c_str(), query.length());
    
        // Fehler abfangen
    	if (errorNumber != 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    // Abfrageergebnis
    // Vorsicht: hier normalerweise mysql_store_result verwenden
    // näheres siehe Doku der mysql c-api
    MYSQL_RES * result = mysql_use_result(m_dbHandle);
    errorNumber =  mysql_errno(m_dbHandle);
    
        // Fehler abfangen
    	if (errorNumber != 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    	// Wenn ein Ergebnis vorliegt
        if (result != NULL)
        {
        int numberCols = mysql_num_fields(result);
    
            // über alle Zeilen drüberlaufen
            while (MYSQL_ROW row = mysql_fetch_row(result))
            {
            // die Datenlängen der einzelnen Felder
            // (für Binärdaten?)
            unsigned long * lengths = mysql_fetch_lengths(result);
    
                     // über alle Spalten drüberlaufen
                     for (int col = 0; col < numberCols; col ++)
                     {
                     std::cout<<row[col]<<", ";
                     }
    
            std::cout<<std::endl;
            }
        }
    
    // Ergebnis freigeben
    mysql_free_result(result);
    
    // Verbindung trennen
    mysql_close(m_dbHandle);
    
    // embedded server beenden
    mysql_server_end();
    
    return EXIT_SUCCESS;
    }
    

    Zwei Anmerkungen:
    War grad zu faul, mir ne neue Importlib zu erstellen,
    drum wird oben mysql_real_query() und mysql_use_result() anstatt
    mysql_query() und mysql_store_result() verwendet.

    Weiteres vorgehen:
    eine my.ini erstellen und ins selbe Verzeichnis wie die entstandene exe kopieren
    (Inhalt: siehe Beitrag oben)

    im mysql-Installationsverzeichnis nach errmsg.sys und errmsg.txt suchen, beide Dateien auch zu der exe ins Verzeichnis kopieren

    Im Verzeichnis mit der exe einen Unterordner "data" erstellen

    Fertig.



  • Hi,
    es tut 😃 😃
    Ich kanns noch nicht ganz glauben, aber es tut! So lang hab ich noch selten gebraucht, um ein Problem zu lösen. Und wie erwartet, wars was ganz Banales:
    Das Data-Verzeichnis hat gefehlt! Steht aber irgendwie auch nix davon in meinem Buch oder sonstwo, wo ich geschaut hab. Na, egal.
    Vielen Dank für eure ausdauernde Hilfe.

    Gruß Squeegee



  • anonymus schrieb:

    Zwei Anmerkungen:
    War grad zu faul, mir ne neue Importlib zu erstellen,
    drum wird oben mysql_real_query() und mysql_use_result() anstatt
    mysql_query() und mysql_store_result() verwendet.

    Das will mir jetzt nicht einleuchten...
    Die MySQL-Hilfe sagt zu mysql_real_query nur:

    You must use mysql_real_query() rather than mysql_query() for queries that contain binary data, because binary data may contain the ‘\0’ character. In addition, mysql_real_query() is faster than mysql_query() because it does not call strlen() on the query string.

    und ob mysql_use_result und mysql_store_result ist auch eine Frage dessen, was mach machen möchte/welche Umstände gegeben sind:

    mysql_store_result() reads the entire result of a query to the client, allocates a MYSQL_RES structure, and places the result into this structure.

    mysql_use_result() initiates a result set retrieval but does not actually read the result set into the client like mysql_store_result() does. Instead, each row must be retrieved individually by making calls to mysql_fetch_row(). This reads the result of a query directly from the server without storing it in a temporary table or local buffer, which is somewhat faster and uses much less memory than mysql_store_result(). The client allocates memory only for the current row and a communication buffer that may grow up to max_allowed_packet bytes.

    On the other hand, you shouldn't use mysql_use_result() if you are doing a lot of processing for each row on the client side, or if the output is sent to a screen on which the user may type a ^S (stop scroll). This ties up the server and prevent other threads from updating any tables from which the data is being fetched.

    When using mysql_use_result(), you must execute mysql_fetch_row() until a NULL value is returned, otherwise, the unfetched rows are returned as part of the result set for your next query. The C API gives the error Commands out of sync; you can't run this command now if you forget to do this!

    You may not use mysql_data_seek(), mysql_row_seek(), mysql_row_tell(), mysql_num_rows(), or mysql_affected_rows() with a result returned from mysql_use_result(), nor may you issue other queries until the mysql_use_result() has finished. (However, after you have fetched all the rows, mysql_num_rows() accurately returns the number of rows fetched.)



  • Hallo Squeegee
    Ist zwar schon ne Weile her, dass du die Fragen hier gestellt hast, aber vielleicht antwortest du ja noch mal 😕
    Wie ich gelesen habe, hast du dir vor einiger Zeit genau die selbe Frage gestellt wie ich. Und zwar das Problem mit den Linkererrors beim Versuch die C API in Visual Studio einzubinden.

    Ich habe MySQL ganz normal installiert, die lymaysql.dll ins system32 Verzeichnis kopiert und die Libs und Header eingebunden. Trotzdem ne lange Liste voller Headerfehler. Was hast du damals für #defines eintragen müssen um das los zu bekommen?

    Gruß Curry



  • Hi Curry,
    was genau willst du denn machen? Über die C-Api Zugriff auf einen laufenden Mysql-Server realisieren (dazu benötigst du die von dir beschriebene libmysql.dll und die libmysql.lib) oder willst du einen embedded Server erstellen, also einen mysql-Server mit in dein Programme integrieren (dazu benötigst du die libmysld.dll und die libmysld.lib). Was für Fehlermeldungen bekommst du denn genau? Ich hatte da ne ganze Reihe von verschiedenen Fehlern. 😃
    Defines hab ich allerdings gar keine gebraucht.
    Welche Version von Visual benützt du? .net?

    Gruß Squeegee



  • Squeegee schrieb:

    Das Data-Verzeichnis hat gefehlt! Steht aber irgendwie auch nix davon in meinem Buch oder sonstwo, wo ich geschaut hab.

    Dann hast du also das hier
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-119360-and-postdays-is-0-and-postorder-is-asc-and-start-is-0.html#862525

    oder auch das hier (untere Hälfte)
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-119360-and-postdays-is-0-and-postorder-is-asc-and-start-is-0.html#862591

    nicht angeschaut 😮

    @ -=]xXx[=-:
    hast schon recht, es kommt drauf an, was man machen möchte.
    Aber ich denk mal, dass ein mysql_store_result() die besser Lösung
    ist, wenn man nicht vorhat, das ganze Recordset selber zu verwalten...
    (Wiederverwendung von Speicher...)



  • Nimm mysql_store_result wenn es nichts ausmacht die ganze Ergebnismenge in den Speicher des Clients zu lesen.
    Dadurch hat man auch bestimmte feature (mysql_funktionen) die weitere Infos liefern. (Anzahl der Datensätze aus der Ergebnismenge, Spalteninfos, man kann selbst vor und zurück durch das Ergebnis gehen). Das geht mit use__result nicht.
    Es gibt sicher Fälle wo use_result verwendung findet. use_reult kann aber den Server blockieren.


Anmelden zum Antworten