Connexion Perl envolée !?
kij_82
Messages postés
4089
Date d'inscription
Statut
Contributeur
Dernière intervention
-
-
-
Bonjours à tous,
J'ai un gros problème dans mon programme dont voici l'exlication :
Ce programme mélange du C et du Perl, mais le probleme vient plus du Perl, donc...
J'ai le main en C suivant :
Ce main a pour role d'établir l'environnement Perl donc et fait appel aux deux fonctions "Connexion" et "RqtPerl"
Voici le code de Connexion :
Cette fonction fait appel à la fonction Perl 'connexion' situé dans Bidon.pm et qui est chargé de créer un objet connexion (qui établi la connexion sur une DB).
La valeur retourné dans le C est une référence sur l'objet connexion créé et je la stocke dans une varable globale définie dans une .h :
Voici le code de Bidon.pm et Connexion.pm :
Bidon.pm :
Et Connexion.pm dont Bidon.pm fait appel :
Voilà, donc, ensuite le code de la fonction C nommée 'RqtPerl' :
Cette fonction execute une ou plusieur requete passée ne paramètre.. cette fonction ne pose aucun probleme.
Elle appelle la fonction Perl 'lance' du fichier 'Bidon.pm' et dont le code est donné ci-dessus.
'lance' appelle d'autre fonction Perl située dans 'Connexion.pm' et dans 'Rqt.pm' dont voici le code :
Rqt.pm :
Le but de ce fichier est la création d'u objet requete, puis l'éxécution de cette requete.. et c'est la que mon probleme survient en fait :
La requete ne peut pas s'éxécuter car l'objet de connexion qui est passé en paramètre à la fonction 'lance' de 'Bidon.pm' est <u>vide</u>!!
Cet objet connexion est créé comme je l'ai dit plus haut dans la première fonction C et est stocké dans la variable globale connexion (de type SV *).
Elle n'est pas nulle lorsque je la passe en paramètre à 'lance', et 'lance' recoit bien deux paramètres (la connexion et une requete). Seulement si je met une trace pour afficher le contenu de la variable '$connexion' récupérée au début de la fonction 'lance', rien ne s'affiche (valeur nulle donc..).
Je pense donc que je passe mal la connexion en paramètre, ou alors que je la récupère mal de ma première fonction, ou alors les deux (m'étonnerais pas !).
Je vous demande donc votre avis à tous la dessus, est-ce que vous voyez d'ou peut venir l'erreur ?
merci beaucoup d'avance.
++
J'ai un gros problème dans mon programme dont voici l'exlication :
Ce programme mélange du C et du Perl, mais le probleme vient plus du Perl, donc...
J'ai le main en C suivant :
int main (int argc, char **argv, char **env) { char *args[] = { "select * from question" }; char *embedding[] = { "", "Bidon.pm" }; time_t deb, fin; int arg = 2, i, j, nbligne, nbchamp; char ***retour; time(&deb); my_perl = perl_alloc(); // PL_perl_destruct_level = 1; perl_construct(my_perl); perl_parse(my_perl, xs_init, arg, embedding, NULL); Connexion(); retour = RqtPerl(args,sizeof(args) / sizeof(args[0]), &nbligne, &nbchamp); perl_destruct(my_perl); perl_free(my_perl); time(&fin); printf("Temp execution = %d secondes\n",fin-deb); printf("%d et %d\n",sizeof(**retour),sizeof(*retour)); printf("\n\nEcriture du retour :\n\n"); for(i=0; i< nbligne; i++){ for(j=0; j < nbchamp; j++){ printf("%s ",retour[i][j]); } printf("\n"); } }
Ce main a pour role d'établir l'environnement Perl donc et fait appel aux deux fonctions "Connexion" et "RqtPerl"
Voici le code de Connexion :
static void Connexion ( ) { int count = 0; dSP; ENTER; SAVETMPS; PUSHMARK(SP); // Empilement des paramètres de connexion à la base : printf("%s %s %s %s\n",driver,base,pwd,user); XPUSHs(sv_2mortal(newSVpv(driver,0))); XPUSHs(sv_2mortal(newSVpv(base,0))); XPUSHs(sv_2mortal(newSVpv(user,0))); XPUSHs(sv_2mortal(newSVpv(pwd,0))); PUTBACK; count = perl_call_pv("connexion", G_SCALAR ); printf("retour = %d\n",count); if( count == 1 ) { printf("retour connexion\n"); connexion = POPs; } else { connexion = NULL; printf("retour de connexion NULL\n"); } PUTBACK; FREETMPS; LEAVE; }
Cette fonction fait appel à la fonction Perl 'connexion' situé dans Bidon.pm et qui est chargé de créer un objet connexion (qui établi la connexion sur une DB).
La valeur retourné dans le C est une référence sur l'objet connexion créé et je la stocke dans une varable globale définie dans une .h :
SV *connexion
Voici le code de Bidon.pm et Connexion.pm :
Bidon.pm :
#!C:\Perl\bin\perl.exe use strict; use lib 'C:/Documents and Settings/stvivotn/Mes documents/essais/debug/'; use Rqt; use Connexion; sub connexion { # Réception des paramètres de connexion: my $DRIVER = shift; my $BASE = shift; my $USER = shift; my $PWD = shift; # Création d'une connexion à la base pour toute la durée du programme. my $connexion = Connexion->new($DRIVER,$BASE,$USER,$PWD); return \$connexion; } sub deconnexion { my ($self) = shift; $self->deconnexion(); print "deconnexion"; } sub lance { my $nb = @_; print "nb = $nb\n"; my $connexion = shift; print "con = $connexion\n"; my $i = 0; my $resultats; my @list; ####print "nb arguments de la liste = $nb\n"; # Traitement des paramètres : while( $i < $nb ) { print "boucle $i\n"; my $sql = $_[$i++]; # Recherche du mot clé de la requete: if( $sql =~ /select/ ) { print "entree select\n"; my $rqt; ($rqt,@list) = Rqt->new(1,$sql,$connexion); #push(@list,$resultat); ###print "Nb lignes affectees par selection = $rqt :\n"; if($rqt =~ /0E0/){ $rqt = 0; } } elsif( $sql =~ /insert/ ) { my ($rqt) = Rqt->new(2,$sql,$connexion); if($rqt =~ /0E0/){ $rqt = 0; } print "Nb lignes affectees par insertion = $rqt\n"; push(@list,$rqt); } elsif( $sql =~ /delete/ ) { my ($rqt) = Rqt->new(3,$sql,$connexion); if($rqt =~ /0E0/){ $rqt = 0; } print "Nb lignes affectees par suppression = $rqt\n"; push(@list,$rqt); } elsif( $sql =~ /update/ ) { my ($rqt) = Rqt->new(4,$sql,$connexion); if($rqt =~ /0E0/){ $rqt = 0; } print "Nb lignes affectees par update = $rqt\n"; push(@list,$rqt); } else { print "Pas de correspondance de mot cle\n"; } } return \@list; }
Et Connexion.pm dont Bidon.pm fait appel :
package Connexion; use DBI; use strict; use lib 'C:/Documents and Settings/stvivotn/Mes documents/essais/debug/'; ############################## # CONSTRUCTEUR # # @param : # # driver / base / user / pwd # ############################## sub new { #print "entre dans Connexion\n"; my $classouref = shift; my $class = ref($classouref) || $classouref; print $class."\n"; # vérification des arguments : my $nb = @_; print $nb."\n"; die "Connexion intérrompue : Connexion::new : arg != 4\n" if ($nb != 4 ); my($driver, $base, $user, $pwd) = @_; print "driver = $driver, base = $base, pwd = $pwd, user = $user\n"; # tentative d'établissement de la connexion : my $dbh = DBI->connect("DBI:".$driver.":".$base,$user,$pwd, {RaiseError => 1, AutoCommit => 0 }) or die $DBI::errstr; my $self = {}; $self->{'connexion'}=$dbh; bless ($self, $class); # retourne l'identifiant de connexion brute et non un objet Connexion. return \$self; } sub get_connexion { my ($self) = shift; return ($self->{'connexion'}); } sub deconnexion { my $self = shift; $self->{'connexion'}->disconnect(); } 1;
Voilà, donc, ensuite le code de la fonction C nommée 'RqtPerl' :
static char *** RqtPerl(char * arg[], int taille, int *nbligne, int *nbchamp) { int count = 0, i = 0, j=0; // Pointeur sur pointeur sur pointeur sur char retourné // par la fonction. Représente le tableau à double entrée // des lignes retournée lors d'une requete de type 'SELECT' : char ***tableau = NULL; // Pointeur sur les éléments de la pile et du tableau // retourné par le Perl en cas de requete de type 'SELECT' : SV *tmp, *champ; AV *tab, *ligne; // initialise le pointeur de pile dSP; ENTER; // tout ce qui est cree a partir d'ici est une variable temporaire SAVETMPS; // sauvegarde du pointeur de pile PUSHMARK(SP); printf("connexion de la forme : %s\n",(char *)connexion); // depos des requetes dans la pile : XPUSHs(sv_2mortal(newSVsv(SvRV(connexion)))); while( i < taille ) XPUSHs(sv_2mortal(newSVpv(arg[i++],0))); // rend global le pointeur local de pile PUTBACK; // appelle la fonction count = perl_call_pv("lance", G_ARRAY); // rafraichit le pointeur de pile pour avoir les élément // retourné par la fonction Perl 'lance' appellée. SPAGAIN; // Un objet est retourné sur la pile : if(count != 0) { printf("retour C = %d\n",count); // Onrécupère cet objet qui est de type tableau : tab = (AV *) SvRV(POPs); *nbligne = av_len(tab)+1; tableau = malloc((*nbligne) * sizeof( **tableau) ); i=0; while( i < (*nbligne) ) { tmp = *av_fetch(tab, i, 0); if( SvTYPE(SvRV(tmp)) == SVt_NV ){ printf("Entier de taille %d\n",SvLEN(tmp)); } else if(SvTYPE(SvRV(tmp)) == SVt_PVAV ) { ligne = (AV *) SvRV(tmp); (*nbchamp) = av_len(ligne)+1; tableau[i] = malloc((*nbchamp) * sizeof( *tableau )); for( j=0; j<(*nbchamp); j++ ) { champ = *av_fetch(ligne, j, 0); tableau[i][j] = malloc( sizeof( SvLEN(champ) ) ); strcpy(tableau[i][j], (char *)SvRV(champ)); } } i++; } } // retire la valeur de retour de la pile PUTBACK; // libere la valeur de retour FREETMPS; // Et retire les arguments empiles LEAVE; // La liste des champ et des lignes est alors retournée avec // pour valeur le résultat d'une requete select ou NULL : return tableau; }
Cette fonction execute une ou plusieur requete passée ne paramètre.. cette fonction ne pose aucun probleme.
Elle appelle la fonction Perl 'lance' du fichier 'Bidon.pm' et dont le code est donné ci-dessus.
'lance' appelle d'autre fonction Perl située dans 'Connexion.pm' et dans 'Rqt.pm' dont voici le code :
Rqt.pm :
package Rqt; use strict; use lib 'C:/Documents and Settings/stvivotn/Mes documents/essais/debug/'; ############################################ # CONSTRUCTEUR # # @param : # # driver / base / user / pwd / [connexion] # ############################################ sub new { my $classouref = shift; my $class = ref($classouref) || $classouref; # vérification du nombre de paramètre passés au constructeur : my $nbparam = @_; die 'Usage : Rqt->new($mode,$requete,$connexion)\n' if($nbparam != 3); my $self = {}; $self->{'mode'} = shift; # mode requete $self->{'sql'} = shift; # requete my $conn = shift; print "connexion dans rqt -> new = $conn\n"; $self->{'connexion'} = $conn; # connexion base bless ($self, $class); $self->execute_sql(); } sub execute_sql { my ($self) = shift; die 'Usage Rqt->execute_sql($connexion)\n' if( (my $nb = @_) != 0); my $ret; my ( $sth ); eval { $sth = $self->{'connexion'}->get_connexion()->prepare( $self->{'sql'} ); $ret = $sth->execute( ); }; die "Erreur d execution\n" if $@; # Si la requete est une selection, on retourne le nombre # de ligne et le résultat de la sélection. if($self->{'mode'} == '1') { #my @list_champ = @{ $sth->{ NAME } }; my @rqt_retour; while ( my @row = $sth->fetchrow_array ) { push(@rqt_retour,\@row); } return ($ret,@rqt_retour); } else { return $ret; } } 1;
Le but de ce fichier est la création d'u objet requete, puis l'éxécution de cette requete.. et c'est la que mon probleme survient en fait :
La requete ne peut pas s'éxécuter car l'objet de connexion qui est passé en paramètre à la fonction 'lance' de 'Bidon.pm' est <u>vide</u>!!
Cet objet connexion est créé comme je l'ai dit plus haut dans la première fonction C et est stocké dans la variable globale connexion (de type SV *).
Elle n'est pas nulle lorsque je la passe en paramètre à 'lance', et 'lance' recoit bien deux paramètres (la connexion et une requete). Seulement si je met une trace pour afficher le contenu de la variable '$connexion' récupérée au début de la fonction 'lance', rien ne s'affiche (valeur nulle donc..).
Je pense donc que je passe mal la connexion en paramètre, ou alors que je la récupère mal de ma première fonction, ou alors les deux (m'étonnerais pas !).
Je vous demande donc votre avis à tous la dessus, est-ce que vous voyez d'ou peut venir l'erreur ?
merci beaucoup d'avance.
++
A voir également:
- Connexion Perl envolée !?
- Gmail connexion - Guide
- Connexion chromecast - Guide
- Gmail connexion autre compte - Guide
- Site inaccessible n'autorise pas la connexion - Guide
- Connexion sctr - Forum Discord
6 réponses
pouffff.... t'as vu ce que tu nous demandes de lire ??? on dirait la constitution
européenne ( trop long ) !!!--
-- je vis dans un rêve dont je ne me reveille jamais...--
<---- j adore ma voisine ;) ---->
européenne ( trop long ) !!!--
-- je vis dans un rêve dont je ne me reveille jamais...--
<---- j adore ma voisine ;) ---->
trop long car tu ne caonnais pas le Perl mais pour qui sais le Perl, c'est relaltivement simple car il s'agit d'objet, méthodes, ... sauf peut etre pour la partie C ou c'est un peu plus barbare peut etre...
Faites ce que je dis mais pas ce que je fais...
http://www.commentcamarche.net/forum/affich-1514037-Puissance-4#1
++
http://www.commentcamarche.net/forum/affich-1514037-Puissance-4#1
++
Je sais bien mais la je suis tellement désespéré que je tente le tout pour le tout !!
Mon pb c'est comme si tu met une pomme de pin (que tu prend dans ton sceau) dans un tuyaux (non troué) en descente, que tu attend la pomme de pin en bas, mais jamais elle n'arrive... alors tu inspecte ton tuyaux... tu te dit, bon, ben elle doit etre par la... pis en fait faite plus de pomme de pin !!
La tu te dit "merde alors j'ai loupé un épisode !", des fois que, on ne sais jamais tu jette un oeil dans ton sceau et qu'es tu vois la au fond, tranquille en train de faire bronzette !!! Ta pomme de pin de merde !!
Bon ben voilà ou j'en suis arrivé.... au fond du sceau ! Je ne peux que lever les yeux au ciel et attendre un miracle de la vie...
Mon pb c'est comme si tu met une pomme de pin (que tu prend dans ton sceau) dans un tuyaux (non troué) en descente, que tu attend la pomme de pin en bas, mais jamais elle n'arrive... alors tu inspecte ton tuyaux... tu te dit, bon, ben elle doit etre par la... pis en fait faite plus de pomme de pin !!
La tu te dit "merde alors j'ai loupé un épisode !", des fois que, on ne sais jamais tu jette un oeil dans ton sceau et qu'es tu vois la au fond, tranquille en train de faire bronzette !!! Ta pomme de pin de merde !!
Bon ben voilà ou j'en suis arrivé.... au fond du sceau ! Je ne peux que lever les yeux au ciel et attendre un miracle de la vie...
mdr :-D
elle s'est bien foutue de ta gueule la pomme de pin...
par contre je savais pas qu'on pouvait appeler du C dans du perl. C'est fou ce qu'on peut faire avec ça quand même !
PS : et désolé j'ai lu ton code, mais je n'ai rien compris... donc peux po t'aider... bon courage quand même !
elle s'est bien foutue de ta gueule la pomme de pin...
par contre je savais pas qu'on pouvait appeler du C dans du perl. C'est fou ce qu'on peut faire avec ça quand même !
PS : et désolé j'ai lu ton code, mais je n'ai rien compris... donc peux po t'aider... bon courage quand même !
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question