Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Aide | Shop Recherche
461 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Connecteur C / MariaDB

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Connecteur C / MariaDB

n°2336916
_pollux_
パリ居住者
Posté le 18-07-2019 à 15:15:01  profilanswer
 

Salut, je galère...
 
Je souhaite faire une application en C qui récupère des données d'un broker MQTT pour les stocker dans une bdd MariaDB.
Je m'en sors globalement, sauf au moment de l'insertion du DATETIME.
 
Il m'a fallut déjà un jour pour comprendre que je ne pouvais pas mettre un simple string correctement formaté mais qu'il fallait une structure MYSQL_TIME. :o
Maintenant, le programme plante sans explication. Par d'erreur SQL, rien, ça sort du programme avec l'erreur suivante :  
 

Citation :

Program received signal SIGSEGV, Segmentation fault.
In mysql_stmt_warning_count () (C:\Users\c.dutriez\Documents\Programmation_EVO2\usage_evo2\bin\Debug\libmariadb.dll)
#3  0x00401f30 in main (argc=1, argv=0xd2ef0) at C:\Users\c.dutriez\Documents\Programmation_EVO2\usage_evo2\main.c:375
C:\Users\c.dutriez\Documents\Programmation_EVO2\usage_evo2\main.c:375:10954:beg:0x401f30
At C:\Users\c.dutriez\Documents\Programmation_EVO2\usage_evo2\main.c:375
#3  0x00401f30 in main (argc=1, argv=0xd2ef0) at C:\Users\c.dutriez\Documents\Programmation_EVO2\usage_evo2\main.c:375
C:\Users\c.dutriez\Documents\Programmation_EVO2\usage_evo2\main.c:375:10954:beg:0x401f30


 
 
voici une partie du programme :
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <mosquitto.h>
  5. #include <usage_evo2.h>
  6. #include <mysql.h>
  7. #include <time.h>
  8. char evo2msg[16];
  9. char evo2tps[20];
  10. int evo2grille;
  11. int evo2coiffe;
  12. int evo2ddv;
  13. int evo2vitessemoteur;
  14. int evo2consigne;
  15. int evo2cartouche;
  16. int evo2omron;
  17. MYSQL_TIME timestamp;
  18. char* getPayload (char *message);
  19. char* getTimestamp (char *message);
  20. void my_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message);
  21. void my_connect_callback(struct mosquitto *mosq, void *userdata, int result);
  22. void my_subscribe_callback(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos);
  23. void my_log_callback(struct mosquitto *mosq, void *userdata, int level, const char *str);
  24. static void show_mysql_error(MYSQL *mysql);
  25. static void show_stmt_error(MYSQL_STMT *stmt);
  26. int main(int argc, char *argv[]){
  27.     MYSQL *mysql;
  28.     MYSQL_STMT *stmt;
  29.     MYSQL_BIND bind[10];
  30.     timestamp.year = 2002;
  31.     timestamp.month = 10;
  32.     timestamp.day = 5;
  33.     timestamp.hour = 11;
  34.     timestamp.minute = 57;
  35.     timestamp.second = 34;
  36.     timestamp.
  37. /* MQTT parameters */
  38. char *host = "localhost";
  39. int port = 1883;
  40. int keepalive = 10;
  41. bool clean_session = true;
  42. struct mosquitto *mosq = NULL;
  43.  /* MYSQL parameters */
  44.     char *payload[] = {"0123456789ABCDEF"};
  45.     int omron[] = {0};
  46.     int coiffe[] = {0};
  47.     int grille[] = {0};
  48.     int vitesse_moteur[] = {0};
  49.     int ddv[] = {0};
  50.     int consigne[] = {0};
  51.     int defaut[] = {0};
  52.     unsigned long payload_length[]= {16};
  53.     char forename_ind[]= {STMT_INDICATOR_NTS};
  54.     char id_ind[]= {STMT_INDICATOR_NULL};
  55.     unsigned int array_size= 1;
  56. /* clock parameters */
  57. clock_t t1,t2;
  58. clock_t t_intervalle = 5000;
  59. mosquitto_lib_init();
  60. mosq = mosquitto_new("timestamp456", clean_session, NULL);
  61.  if(!mosq){
  62.  fprintf(stderr, "Error: Out of memory.\n" );
  63.  return 1;
  64. }
  65. /* callback fonctions */
  66. mosquitto_username_pw_set(mosq, "application", "timestamp456" );
  67. mosquitto_log_callback_set(mosq, my_log_callback);
  68. mosquitto_connect_callback_set(mosq, my_connect_callback);
  69. mosquitto_message_callback_set(mosq, my_message_callback);
  70. mosquitto_subscribe_callback_set(mosq, my_subscribe_callback);
  71. if(mosquitto_connect(mosq, host, port, keepalive)){
  72.  fprintf(stderr, "Unable to connect.\n" );
  73.  return 1;
  74. }
  75. mysql= mysql_init(NULL);
  76.     t2 = clock();
  77.     if (!mysql_real_connect(mysql, "localhost", "nom", "mdp","usage_db", 0, "/tmp/mysql.sock", 0)) show_mysql_error(mysql);
  78.     if (mysql_query(mysql, "DROP TABLE IF EXISTS bulk_example3" )) show_mysql_error(mysql);
  79.     if (mysql_query(mysql, "CREATE TABLE IF NOT EXISTS evo2_usage (\
  80.         id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,\
  81.         datemsg CHAR(20),\
  82.         message CHAR(16),\
  83.         omron SMALLINT,\
  84.         coiffe SMALLINT,\
  85.         grille SMALLINT,\
  86.         vitesse_moteur SMALLINT,\
  87.         ddv SMALLINT,\
  88.         consigne SMALLINT,\
  89.         cart SMALLINT)" )) show_mysql_error(mysql);
  90.     while(1){
  91.     t1 = clock();
  92.         if (t1-t2 > t_intervalle){
  93.             t2 = t1;
  94.             mosquitto_loop(mosq,-1,1);
  95.             payload[0]= evo2msg;
  96.             //timestamp[0]= evo2tps;
  97.             omron[0] = evo2omron;
  98.             coiffe[0] = evo2coiffe;
  99.             grille[0] = evo2grille;
  100.             vitesse_moteur[0] = evo2vitessemoteur;
  101.             ddv[0] = evo2ddv;
  102.             consigne[0] = evo2consigne;
  103.             defaut[0] = evo2cartouche;
  104.                 stmt= mysql_stmt_init(mysql);
  105.                 if (mysql_stmt_prepare(stmt, "INSERT INTO evo2_usage VALUES (?,?,?,?,?,?,?,?,?,?)", -1)){
  106.                     show_stmt_error(stmt);
  107.                     printf("ca plante la\n" );
  108.                 }
  109.                 memset(bind, 0, sizeof(MYSQL_BIND) * 10);
  110.                 /* We autogenerate id's, so all indicators are STMT_INDICATOR_NULL */
  111.                 bind[0].u.indicator= id_ind;
  112.                 bind[0].buffer_type= MYSQL_TYPE_LONG;
  113.                 bind[1].buffer= (char *)&timestamp;          //datetime
  114.                 bind[1].buffer_type= MYSQL_TYPE_DATETIME;
  115.                 bind[1].is_null= 0;
  116.                 bind[1].length= 0;
  117.                 bind[2].buffer= payload;                        // msg entier
  118.                 bind[2].buffer_type= MYSQL_TYPE_STRING;
  119.                 bind[2].length= payload_length;
  120.                 bind[3].buffer = omron;                         // OMRON (vent)
  121.                 bind[3].buffer_type= MYSQL_TYPE_LONG;
  122.                 bind[3].u.indicator= forename_ind;
  123.                 bind[4].buffer = coiffe;                        // coiffe
  124.                 bind[4].buffer_type= MYSQL_TYPE_LONG;
  125.                 bind[4].u.indicator= forename_ind;
  126.                 bind[5].buffer = grille;                        // grille
  127.                 bind[5].buffer_type= MYSQL_TYPE_LONG;
  128.                 bind[5].u.indicator= forename_ind;
  129.                 bind[6].buffer = vitesse_moteur;                // vitesse_moteur
  130.                 bind[6].buffer_type= MYSQL_TYPE_LONG;
  131.                 bind[6].u.indicator= forename_ind;
  132.                 bind[7].buffer = ddv;                           // ddv
  133.                 bind[7].buffer_type= MYSQL_TYPE_LONG;
  134.                 bind[7].u.indicator= forename_ind;
  135.                 bind[8].buffer = consigne;                      // consigne
  136.                 bind[8].buffer_type= MYSQL_TYPE_LONG;
  137.                 bind[8].u.indicator= forename_ind;
  138.                 bind[9].buffer = defaut;                        // défaut
  139.                 bind[9].buffer_type= MYSQL_TYPE_LONG;
  140.                 bind[9].u.indicator= forename_ind;
  141.                 /* set array size */
  142.                 mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
  143.                 /* bind parameter */
  144.                 mysql_stmt_bind_param(stmt, bind);
  145.                 printf("ERREUR" );
  146.                
  147.                 /* execute */
  148.                 if (mysql_stmt_execute(stmt))
  149.                 show_stmt_error(stmt);
  150.                 printf("INSCRIPTION" );
  151.             }
  152.     }
  153. mosquitto_destroy(mosq);
  154. mosquitto_lib_cleanup();
  155.     mysql_stmt_close(stmt);
  156.     mysql_close(mysql);
  157.     return 0;
  158. }


 
Pour info, j'ai bien le message ERREUR qui s'affiche, mais pas celui ISNCRIPTION, ça plante donc bien après le paramétrage de stmt, mais pendant son exécution.
Si vous avez une piste, je suis preneur. PS : si à la place de datetime, je remplace par n'importe quelle autre type de données (string, ....), la donnée s'inscrit dans la BDD sans problème.


Message édité par _pollux_ le 18-07-2019 à 15:26:50

---------------
Le topic du sport électronique@hfr : watch the l33t !
mood
Publicité
Posté le 18-07-2019 à 15:15:01  profilanswer
 

n°2336966
rat de com​bat
attention rongeur méchant!
Posté le 19-07-2019 à 18:51:38  profilanswer
 

Je suppose que tu compiles déjà avec -Wall -Werror ou un truc semblable et que ça ne sors rien?
C'est quoi usage_evo2.h? Le moteur de recherche ne connaît pas...
Essaye de simplifier ton problème en virant la partie MQTT et si possible le evo_mystère, ça sera plus facile (même déjà possible) pour nous de compiler et débugger ce truc.

n°2336975
gilou
Modérateur
Modzilla
Posté le 20-07-2019 à 09:10:09  profilanswer
 

bind[1].is_null= 0;
 bind[1].length= 0;
 [:sovxx]  
Si je lis bien la doc, https://dev.mysql.com/doc/refman/8. [...] tures.html
is_null is a pointer to a boolean scalar, not a boolean scalar,  
donc ça fait un premier truc qui me semble plantogène, et
For input parameter data binding, set *length to indicate the actual length of the parameter value stored in *buffer.
donc on devrait avoir  
size_t timesize = sizeof(MYSQL_TIME);
bind[1].buffer_type= MYSQL_TYPE_DATETIME;
bind[1].length=&timesize;  
bind[1].buffer_length=timesize;  
bind[1].buffer= (char *)&timestamp;
et ça devrait suffire, non?
 
A+,


Message édité par gilou le 20-07-2019 à 11:35:33

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
n°2336976
_pollux_
パリ居住者
Posté le 20-07-2019 à 09:41:51  profilanswer
 

J'ai pas la main là dessus tout de suite, mais je promets de regarder ça de plus prêt :D

 

Comme je débute en C, je maitrise pas forcément très bien les pointeurs : par exemple, (char *)&timestamp, j'ai pas encore compris comment ça marche :D


Message édité par _pollux_ le 20-07-2019 à 13:18:51

---------------
Le topic du sport électronique@hfr : watch the l33t !
n°2336980
rat de com​bat
attention rongeur méchant!
Posté le 20-07-2019 à 14:13:14  profilanswer
 

Tu compiles bien avec -Wall -Werror? Indispensable pour un débutant, surtout quand on bricole les pointeurs! :o

n°2336991
_pollux_
パリ居住者
Posté le 20-07-2019 à 18:16:08  profilanswer
 

Oui, j'utilise code block et gcc. C'est par défaut et je n'ai aucune erreur. Mais j'ai pas encore eu le temps de tester les propositions de gilou. J'étais sur la doc de Maria DB, bien moins complète que celle de mysql.


Message édité par _pollux_ le 20-07-2019 à 18:16:28

---------------
Le topic du sport électronique@hfr : watch the l33t !
n°2337029
_pollux_
パリ居住者
Posté le 22-07-2019 à 10:48:49  profilanswer
 

Pour repartir sur de bonnes bases, la version épurée :

 
Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <mysql.h>
  5. static void show_mysql_error(MYSQL *mysql)
  6. {
  7.   printf("Error(%d) [%s] \"%s\"", mysql_errno(mysql),
  8.                                   mysql_sqlstate(mysql),
  9.                                   mysql_error(mysql));
  10.   exit(-1);
  11. }
  12. static void show_stmt_error(MYSQL_STMT *stmt)
  13. {
  14.   printf("Error(%d) [%s] \"%s\"", mysql_stmt_errno(stmt),
  15.                                   mysql_stmt_sqlstate(stmt),
  16.                                   mysql_stmt_error(stmt));
  17.   exit(-1);
  18. }
  19. int main(int argc, char *argv[])
  20. {
  21.   MYSQL *mysql;
  22.   MYSQL_STMT *stmt;
  23.   MYSQL_BIND bind[4];
  24.   MYSQL_TIME timestamp;
  25.   timestamp.year = 2000;
  26.   timestamp.month = 4;
  27.   timestamp.day = 21;
  28.   timestamp.hour = 5;
  29.   timestamp.minute = 23;
  30.   timestamp.second = 59;
  31.   /* Data for insert */
  32.   const char *surnames[]= {"pollux"};
  33.   unsigned long surnames_length[]= {10};
  34.   const char *forenames[]= {"dog"};
  35.   char forename_ind[]= {STMT_INDICATOR_NTS};
  36.   char id_ind[]= {STMT_INDICATOR_NULL};
  37.   unsigned int array_size= 1;
  38.   mysql= mysql_init(NULL);
  39.   /* connect to MariaDB server */
  40.   if (!mysql_real_connect(mysql, "localhost", "root", "wesh","usage_db", 0, "/tmp/mysql.sock", 0)) show_mysql_error(mysql);
  41.   if (mysql_query(mysql, "DROP TABLE IF EXISTS bulk_example1" ))
  42.     show_mysql_error(mysql);
  43.   if (mysql_query(mysql,"CREATE TABLE bulk_example1 (\
  44.                         id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,\
  45.                         forename CHAR(30) NOT NULL DEFAULT 'unknown',\
  46.                         surname CHAR(30),\
  47.                         date DATETIME)" ))
  48.     show_mysql_error(mysql);
  49.   stmt= mysql_stmt_init(mysql);
  50.   if (mysql_stmt_prepare(stmt, "INSERT INTO bulk_example1 VALUES (?,?,?,?)", -1))
  51.     show_stmt_error(stmt);
  52.   memset(bind, 0, sizeof(MYSQL_BIND) * 4);
  53.   /* We autogenerate id's, so all indicators are STMT_INDICATOR_NULL */
  54.   bind[0].u.indicator= id_ind;
  55.   bind[0].buffer_type= MYSQL_TYPE_LONG;
  56.   bind[1].buffer= forenames;
  57.   bind[1].buffer_type= MYSQL_TYPE_STRING;
  58.   bind[1].u.indicator= forename_ind;
  59.   bind[2].buffer_type= MYSQL_TYPE_STRING;
  60.   bind[2].buffer= surnames;
  61.   bind[2].length= surnames_length;
  62.   bind[3].buffer_type= MYSQL_TYPE_DATETIME;
  63.   bind[3].buffer = (char *)&timestamp;
  64.   bind[3].length = 0;
  65.   bind[3].is_null = 0;
  66.   /* set array size */
  67.   mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
  68.   /* bind parameter */
  69.   mysql_stmt_bind_param(stmt, bind);
  70.   /* execute */
  71.   if (mysql_stmt_execute(stmt))
  72.     show_stmt_error(stmt);
  73.   mysql_stmt_close(stmt);
  74.   mysql_close(mysql);
  75.   return 0;
  76. }


Message édité par _pollux_ le 22-07-2019 à 10:54:29

---------------
Le topic du sport électronique@hfr : watch the l33t !
n°2337030
_pollux_
パリ居住者
Posté le 22-07-2019 à 10:52:27  profilanswer
 

En corrigeant avec la proposition de Gilou,

 


j'ai une erreur de type sur le &timesize. :

Code :
  1. size_t timesize = sizeof(MYSQL_TIME);
  2.     bind[3].buffer_type= MYSQL_TYPE_DATETIME;
  3.     bind[3].length=&timesize;
  4.     bind[3].buffer_length=timesize;
  5.     bind[3].buffer= (char *)&timestamp;
 


C:\C\test2\main.c|3|warning: assignment from incompatible pointer type.


Message édité par _pollux_ le 22-07-2019 à 10:55:09

---------------
Le topic du sport électronique@hfr : watch the l33t !
n°2337033
gilou
Modérateur
Modzilla
Posté le 22-07-2019 à 11:49:18  profilanswer
 

Tu remplaces 1 par  
unsigned long timesize = sizeof(MYSQL_TIME);
et ça devrait coller.
 
Et comme buffer devrait être un void *, au vu de la doc, tu peux aussi tant que tu y es faire pour 5
bind[3].buffer= (void *)&timestamp;
 
A+,


Message édité par gilou le 22-07-2019 à 12:00:52

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
n°2337034
_pollux_
パリ居住者
Posté le 22-07-2019 à 12:26:56  profilanswer
 

ça marche mieux ! enfin, j'en reviens au départ, ça compile avec des données sans doute mieux traitées.

 

Par contre :/ :

Citation :

Program received signal SIGSEGV, Segmentation fault.
In mysql_stmt_warning_count () (C:\C\test2\bin\Debug\libmariadb.dll)
#3  0x00401652 in main (argc=1, argv=0x852ee8) at C:\C\test2\main.c:95
C:\C\test2\main.c:95:2658:beg:0x401652
At C:\C\test2\main.c:95
#3  0x00401652 in main (argc=1, argv=0x852ee8) at C:\C\test2\main.c:95
C:\C\test2\main.c:95:2658:beg:0x401652

 

D'autre part, sachant que :

Citation :

length is ignored for numeric and temporal data types because the buffer_type value determines the length of the data value.

 

J'ai carrément viré la ligne 3, mais ça ne change rien au problème.


Message édité par _pollux_ le 22-07-2019 à 16:01:17

---------------
Le topic du sport électronique@hfr : watch the l33t !
mood
Publicité
Posté le 22-07-2019 à 12:26:56  profilanswer
 

n°2337040
rat de com​bat
attention rongeur méchant!
Posté le 22-07-2019 à 16:35:37  profilanswer
 

Bon désolé, j'ai finalement réussi à compiler le truc mais je sais pas le faire fonctionner, pourtant j'ai investi du temps...

 

Pour ceux qui veulent tester et qui sont sous Debian faut être sous Debian 10.

Message cité 1 fois
Message édité par rat de combat le 22-07-2019 à 16:37:45
n°2337041
_pollux_
パリ居住者
Posté le 22-07-2019 à 16:49:35  profilanswer
 

Merci d'avoir essayé en tout cas :o

 

J'vais essayer de contacter les dev via IRC, parce que je suis bien coincé là :/
ça fait un peu 4 jours que je suis sur cette connerie.


Message édité par _pollux_ le 22-07-2019 à 16:50:00

---------------
Le topic du sport électronique@hfr : watch the l33t !
n°2337042
_pollux_
パリ居住者
Posté le 22-07-2019 à 17:08:12  profilanswer
 

rat de combat a écrit :

Bon désolé, j'ai finalement réussi à compiler le truc mais je sais pas le faire fonctionner, pourtant j'ai investi du temps...
 
Pour ceux qui veulent tester et qui sont sous Debian faut être sous Debian 10.


pourquoi Debian 10 d'ailleurs ?  
 
(j'suis sous windows  [:cerveau eric] )


---------------
Le topic du sport électronique@hfr : watch the l33t !
n°2337053
_pollux_
パリ居住者
Posté le 22-07-2019 à 18:24:11  profilanswer
 

sinon, j'ai trouvé cette page là dans la doc de MYSQL :  
 
https://dev.mysql.com/doc/refman/8. [...] dling.html
mais ça m'aide pas trop :/
 


---------------
Le topic du sport électronique@hfr : watch the l33t !
n°2337054
rat de com​bat
attention rongeur méchant!
Posté le 22-07-2019 à 18:32:11  profilanswer
 

_pollux_ a écrit :


pourquoi Debian 10 d'ailleurs ?  
 
(j'suis sous windows  [:cerveau eric] )

Parce que il faut une version assez récente de MariaDB et celle de Debian 9 semble trop ancienne. J'ai pas poussé trop loin, j'ai changé de machine virtuelle.

n°2337055
_pollux_
パリ居住者
Posté le 22-07-2019 à 18:34:53  profilanswer
 

ok.

 

Bon, personne ne répond sur IRC, semblerait qu'il y ait des plages horaires pour les réponses :D ... par désespoir, j'ai laissé un message ici : https://mariadb.zulipchat.com/#narr [...] ew-members
C'est compliqué de joindre les teams de dev maintenant, on est loin de la facilité d'un forum :o


Message édité par _pollux_ le 22-07-2019 à 18:35:28

---------------
Le topic du sport électronique@hfr : watch the l33t !
n°2337153
_pollux_
パリ居住者
Posté le 24-07-2019 à 14:25:16  profilanswer
 

Bon, problème non résolu frontalement. Cependant, d'un strict point de vue fonctionnel, j'ai fait sans "prepared statement functions" et ça marche.


---------------
Le topic du sport électronique@hfr : watch the l33t !

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Connecteur C / MariaDB

 

Sujets relatifs
Header C dans prog cppC++ calcul d'un nombre prmier
[C#] Charger un combobox plus rapidementRécupération adresse IP de ma Passerelle en C
MariaDB Requête UPDATE JSON_SET sur une colonne NULLDébutant en C rencontre quelques soucis...
codage en language CLogiciel pour développer en C++
[STM32]Implémentation afficheur oled NHD0420CW en I²C 
Plus de sujets relatifs à : Connecteur C / MariaDB


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite) / Groupe LDLC / Shop HFR