[C++] Utilisation de mysql++

Bonjour,

Je suis sur le développement d’un logiciel libre destiné à la compression en masse.
J’ai développé une partie du programme en C, avec la lib mysql sans trop de problème, cependant je dois m’attaquer maintenant à la partie C++ avec mysql++, et n’ayant pas fait de C++ depuis longtemps j’ai un peu du mal B)
[codebox] // Connect to the sample database.
mysqlpp::Connection con(false);

con.connect(« test », « localhost », « toto », « toto »);

if (!con)
{
cerr << "Database connection failed: " << con.error() << endl;
return 1;
}[/codebox]

La connexion à la base se déroule bien, c’est apparement ma création de requete qui merde :
[codebox]mysqlpp::Query query = con.query();
query << « SELECT * FROM slave »;
mysqlpp::Result res = query.store();

cout << « We have: » << endl;
if (res) {
char buf[100];
mysqlpp::Row row;
mysqlpp::Row::size_type i;
for (i = 0; row = res.at(i); ++i) {
cout << ‹ \t › << row.at(0) << endl;
// cout << ‹ \t › << strncpy(buf, row.at(0), sizeof(buf)) << endl;
}
}
else {
cerr << "Failed to get item list: " << query.error() << endl;
return 1;
}
[/codebox]

Le code comme ca, il marque le We have, la premiere valeur du champ de la table, et apres SegFault…
Si je commente le premier cout et décommente le second, il seg fault après le We have :
Résultat, compilé avec ou sans efence :
[codebox] Electric Fence 2.1 Copyright © 1987-1998 Bruce Perens.
We have:
127.0.0.1
Segmentation fault
[/codebox]

et si je commente tout à partir du if (res) :
[codebox] Electric Fence 2.1 Copyright © 1987-1998 Bruce Perens.
We have:

ElectricFence Aborting: free(804d294): address not from malloc().
Illegal instruction
[/codebox]

et sans efence :
[codebox]We have:
*** glibc detected *** free(): invalid pointer: 0x0804de0c ***
Aborted
[/codebox]

Si quelqu’un a une idée, ou si vous pensez que j’ai pu oublier quelque chose, je suis preneur de toute idée, parce que j’ai un peu beaucoup de mal à me remettre au C++ après toutes ces années sans B)

Bon sur ce, je vais m’installer sur ce forum, ca va m’occuper :smiley:
Merci d’avance

T’es sûr que Result::at(size_type i) est protégé contre les valeurs de i trop grandes? C’est pas précisé dans la doc, vérifie.

Je ne suis pas obligé de faire comme ça, je viens de testé ça :

[codebox] mysqlpp::Query query = con.query();
query << “select * from slave”;
mysqlpp::ResUse res = query.use();

// Retreive result rows one by one, and display them.
if (res) {
// Display header
cout.setf(ios::left);
cout << setw(21) << “IP” <<
setw(10) << “Port” <<
setw(10) << “State” <<
endl << endl;

// Get each row in result set, and print its contents
mysqlpp::Row row;
while (row = res.fetch_row()) {
  cout << setw(20) << row["ip"] << ' ' <<
setw(9) << row["port"] << ' ' <<
setw(9) << row["state"] << ' ' <<
endl;
}

return 0;

}
else {
cerr << "Failed to get stock item: " << query.error() << endl;
return 1;
}[/codebox]

mais, toujours pareil, la première occurence suivi d’un segfault :
[codebox]We have:
IP Port State

127.0.0.1 30000 Waiting
Segmentation fault
[/codebox]

Pas d’idée, va falloir debugger et y aller step by step B) T’as pas une callstack au fait ?

Désolé j’ai pas le temps de t’aider maintenant, je crois que j’avais eu le coup, promis je re regarde plus tard voir si je peux t’aider.
Au fait, pourquoi tu fais ça en C++ ?
Mysql++ est une surcouche de mysql tu sais … B) (lib en C)

Edit:

Pfiou que windows est mauvais pour ma productivité, j’ai l’impression que c’est super loin !
Juste en quise de pistes, car faudrait que je me replonge dans l’api pour savoir quelle fonction C est utilisée pour quelle fonction C++ …
en gros il y a une histoire de « si tu fais un query.store » au lieu de « query.use » tu peux acceder a tes données directement (ce que j’avais choisi je crois pour pas m’embeter) => verifier que ta boucle boucle bien dans le cas du query.use, où les résultats ne sont PAS enregistrés…
Je détail un peu ce qui pourrait me faire penser ça : query.use (conditionnel, c’est de mémoire) prends le PREMIER résultat, et doit consulter la base pour avoir le reste.
Ce qui serait cohérent dans la mesure où ton premier résultat marche mais pas les autres …

Mon ptit bout de code, à tester dans ton cas peut-être (par contre le store() est plus lent que use() et pour de nombreuses données c’est peut-être pas top (donc poru de la compréssion de masse …) fin juste pour tester si ça marche ça suffira.
(ps : j’utilise les exceptions moi (donc remplacer le false du constructeur par un with_exception (qui est en fait un typedef de true en gros (je suis pas tres rigoureux car j’ai pas beaucoup dormi, donc j’estime que si on se comprends, ça suffit B)( pff flemme de compter les parentheses)))))

[code]#include « utile.h »

using namespace std;
using namespace mysqlpp;
int main()
{
try
{
mysqlpp::Connection Handler(use_exceptions);
Handler.connect( base, login, pass toussa);
mysqlpp::Query query = Handler.query();
query << « ma requete »;
mysqlpp::Result res = query.store();

if (res)
{
  char buf[100];
  mysqlpp::Row row;
  mysqlpp::Row::size_type i;
  for (i = 0; row = res.at(i); ++i)
  {
	cout << '\t' << utf8trans(row.at(1), buf, sizeof(buf)) << endl;
	cout << utf8trans(row["un champs ici"], buf, sizeof(buf)) << endl;
  }
}

}

catch (const BadQuery& er)
{
cerr << "Query error: " << er.what() << endl;
}
catch (const BadConversion& er)
{
cerr << "Conversion error: " << er.what() << endl;
}
catch (const Exception& er)
{
cerr << "Error: " << er.what() << endl;
}
return 0;
}[/code]

Ptit commentaire : j’invente rien, ça doit pas etre loin d’un copier coller de la doc…
et dans le fichier utile.h j’ai la fonction utfmachin (oui saimal de mettre ça dans un .h) :
http://tangentsoft.net/mysql++/doc/html/userman/unicode.html (je retrouve plus d’où je sors ce util.h … mais je te met quand meme la source des fois que ça marche :smiley:

[code]char*
utf8trans(const char* utf8_str, char* out_buf, int buf_len)
{
#ifdef MYSQLPP_PLATFORM_WINDOWS
// It’s Win32, so assume console output, where output needs to be in
// local ANSI code page by default.
wchar_t ucs2_buf[100];
static const int ub_chars = sizeof(ucs2_buf) / sizeof(ucs2_buf[0]);

// First, convert UTF-8 string to UCS-2
if (MultiByteToWideChar(CP_UTF8, 0, utf8_str, -1,
		ucs2_buf, ub_chars) > 0) {
	// Next, convert UCS-2 to local code page.
	CPINFOEX cpi;
	GetCPInfoEx(CP_OEMCP, 0, &cpi);
	WideCharToMultiByte(cpi.CodePage, 0, ucs2_buf, -1,
			out_buf, buf_len, 0, 0);
	return out_buf;
}
else {
	int err = GetLastError();
	if (err == ERROR_NO_UNICODE_TRANSLATION) {
		cerr << "Bad data in UTF-8 string" << endl;
	}
	else {
		cerr << "Unknown error in Unicode translation: " <<
				GetLastError() << endl;
	}
	return 0;
}

#else
// Assume a modern Unixy platform, where the system’s terminal I/O
// code handles UTF-8 directly. (e.g. common Linux distributions
// since 2001 or so, recent versions of Mac OS X, etc.)
strncpy(out_buf, utf8_str, buf_len);
return out_buf;
#endif
}[/code]

J’espere t’avoir un peu éclairé, mais n’hésite pas si j’ai pas été clair (c’est plus que possible :D)

En fait, nous avons 3 parties pour ce programmes… 3 programmes plutot, 2 sont faite en C, et sont codé et fonctionne correctement, la 3eme utilise des objets, nous avons donc penser au C++…
Cependant je viens de discuter avec le second développeur, et pour la première version, nous risquons de faire cette troisième partie en C, sans objets, on peut tout à fait la faire fonctionner en C, et comme la première version du projet est attendu par certaines personnes, nous allons faire ça, mais, nous devrons recoder cette partie, pour la passer en C++/Objets plus tard, donc si y’a moyen que tu me dises un peu, ça m’aiderait, et vu que c’est plus tres préssé, tu peux prendre ton temps :smiley:

Je sais pas si j’ai été très clair la B)

Merci en tout cas pourvotre aide/idées B)

(j’hésite à faire un up des familles pour montrer que j’ai édité avant que le sujet ne coule …)