Unicode und MySQL C API
-
Hallo Community,
Ich suche bereits nach einiger Zeit nach einer Lösung für mein Problem, aber bisher leider ohne Erfolg. Vielleicht kann mir hier ja jemand weiterhelfen.
Ich habe ein C Programm geschrieben welches auf Unicode basiert (wchar_t). Zur Anbindung an eine MySQL DB benutze ich die C API im MySQL Installationsverzeichnis (mysql.h). Aber es sieht so aus, als gäbe es keine Funktion zur Anfrage mit einem Unicode-String.
Ich habe lediglich diese Funktion gefunden:
mysql_real_query(MYSQL *mysql, const char *q, unsigned long length);Aber ich suche nach etwas wie diese Funktion:
mysql_real_query(MYSQL *mysql, const wchar_t *q, unsigned long length);Kann mir jemand sagen, wie ich mit der MySQL Datenbank kommunizieren kann unter der Verwendung von Unicode? Oder geht das mit dieser API überhaupt nicht? Wenn dem so ist, gibt es eine andere API die das unterstützt?
Danke für Tipps und Hilfen,
MFG,
Ronny
-
mysql unterstützt utf8. du könntest iconv verwenden, um den wchar_t string in einen utf8 string zu konvertieren und den dann in der datenbank speichern.
-
Und wie kann ich den Unicode wieder aus der Datenbank lesen?
Wenn ich eine Anfrage stelle und eine Row mit mysql_fetch_row() hole, liefert mir die ein Array von MYSQL_ROW. Dieser Typ ist definiert als typedef char **MYSQL_ROW.
Da ist demnach schon die Unicode Information verloren.
Vielen Dank,
MFG
-
du darfst ein char array nicht wirklich mit einem array von buchstaben verwechseln. ein char array ist im allgemeine eher ein array von byte. welches charset in diesem byte array liegt, ist der programmiersprache unbekannt. du bekommst einfach wieder utf8 aus der datenbank und musst es nach ucs2 oder ucs4 (ja nachdem, was du vewenden willst) per iconv konvertieren.
-
Danke für den Hinweis.
Im Debugger seh ich nun auch, dass wirklich UTF-8 zurück kommt.
Allerdings komm ich leider mit iconv gar nicht klar.
Ich finde nirgends eine gute Dokumentation oder einfache Beispiele zur Anwendung davon.char *inbuf = row[3]; size_t inbytesleft = strlen(inbuf); const char *inchar; char *outchar; char outbuf[10] = ""; size_t outbytesleft = inbytesleft; iconv_t cd; cd = iconv_open ( "UCS-2","UTF-8"); if (cd == (iconv_t) -1) { // TODO SetError ("Error", NULL); } inchar = inbuf; outchar = outbuf; int x = iconv (cd, &inchar, &inbytesleft, &outchar, &outbytesleft); iconv_close (cd);
Ich hab bestimmt einige Fehler im Code, aber ich versteh noch nicht richtig die Arbeitsweise von iconv. iconv macht zwar irgendwas, aber was genau, kann ich nicht sagen. Jedenfalls wird nichts konvertiert.
Belegung vor dem iconv()-Aufruf:
inchar => "a€rty" inbytesleft => 5 outchar => "" outbytesleft => 5
Belegung nach dem iconv()-Aufruf:
inchar => "€rty" inbytesleft => 4 outchar => "" outbytesleft => 3
Kann mir vielleicht jemand ein kurzes Beispiel zur Anwendung geben? Oder einen Tipp, wie ich o.g. Code richtigerweise gestalten muss?
Vielen Dank,
Ronny
-
dieser link
könnte dir dabei helfen.mir scheint aber deine art, wie du c-strings verwendest, zumindest eigenartig zu sein. dazu fehlt aber leider etwas code. was ist zb. row?
-
Danke, das Beispiel hatte ich schon durchgearbeitet. Aber das Verhalten ist das gleiche wie oben beschrieben.
Row ist ein Datentyp der MySQL Schnittstelle, der die Ergebnismenge hält.
ZB. wenn ich SELECT id, name, alter FROM ... mache, hat Row pro Zeile 3 Einträge (row[0] bis row[2]) usw.Definiert ist es wie folgt:
MYSQL_ROW row = mysql_fetch_row (result);
MYSQL_ROW ist definiert als:
typedef char **MYSQL_ROW; /* return data as array of strings */
mfg
-
Ok, ich habs mit Iconv aufgegeben und nun mit MultiByteToWideChar implementiert und das scheint bisher gut zu funktionieren.
mfg und danke für die Hilfe,
Ronny
-
Alternativ mbstowcs und wcstombs.
-
Alternativ mbstowcs und wcstombs.
Damit geht aber bspw. das €-Zeichen verloren.