C, XS & Per -> Un peu d'aide siouplé :)l

Résolu
kij_82 Messages postés 4089 Date d'inscription   Statut Contributeur Dernière intervention   -  
kij_82 Messages postés 4089 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjours, un petit pb en ce qui concerne l'utilisation de XS pour traitement des retour d'un script Perl :
J'apelle un script Perl qui est sencé me retourné un tableau de hash qui représente les ligne retournées par un SELECT sur une base. Pas de pb jusque là, le truc c'est dans le code C, pour récupérer ce tableau (ou liste de lignes) avec les différentes syntaxe XS, je n'y comprend rien à rien, même 4 semaines après...

Dans le code suivant de ma fonction C :
static void
    PerlPower(char * arg[], int taille)
    {
	
      dSP; 
      int count = 0, i = 0;
      SV *sv = newSV(0);
      SV *ligne = newSV(0);
      I32 taille_tab;
      AV *tab = newAV();

      ENTER;                       
      SAVETMPS;                    
      PUSHMARK(SP);             

      while( i < taille )
         XPUSHs(sv_2mortal(newSVpv(arg[i++],0))); 
      PUTBACK;                       
      count = perl_call_pv("lance", G_ARRAY); 
      SPAGAIN;
                                      
      if(count != 0) {
          printf("Nombre de retour = %d\n",count);

          sv = POPs;
          tab = (AV*) SvRV(sv);
          taille_tab = av_len(tab);
          printf("taille = %d\n",taille_tab);

          i=0;
          while( i < taille_tab-1 )
          {
                sv_setsv(ligne,av_pop(tab));
	printf("coucou %d\n",i);
	i++;
          }
     }
      PUTBACK;					
      FREETMPS; 
      LEAVE;					

    }


Il me met l'erreur habituel comme quoi la mémoire ne peut pas etre read à l'adresse .... L'erreur se situe dans le bloc :
while( i < taille_tab-1 )
          {
                sv_setsv(ligne,av_pop(tab));
	printf("coucou %d\n",i);
	i++;
          }

La taille "taille_tab" est de 3 (c'est ce qu'il me dit ), alors qu'elle devrait etre de deux.

Bref, je ne comprend pas pourquoi il me met cette erreur ?! Qqun saurait (mise à part me dire que je dois pas lire dans un espace autorisé ou alloué).

ps : même en remplacant taille_tab pour la condition du while par 1, il me met l'erreur. --> pb de récup du tableau ? (je n'en douterais pas !!)

merci :)

3 réponses

m0n0-le-14r3 Messages postés 174 Date d'inscription   Statut Membre Dernière intervention   17
 
:D
( un sourire ca fait toujours plaisir )
0
kij_82 Messages postés 4089 Date d'inscription   Statut Contributeur Dernière intervention   857
 
C'est ca, va voir ta voisine !! Et reste-y donc !!!!
@"#!(

8D sacré toi va
0
kij_82 Messages postés 4089 Date d'inscription   Statut Contributeur Dernière intervention   857
 
Bon j'ai réussi à combler le manque de participation aux messages concernant le Perl, ce grace à l'aide de Jedaï que je remercie encore, pour les intéressé (je sais que maitenant on est deux sur ce forum...), voilà la réponse :
#include <EXTERN.h>
#include <perl.h>
#include <time.h>

static PerlInterpreter *my_perl;

static void xs_init (pTHX); 
EXTERN_C void boot_DynaLoader (pTHX_ CV* cv); 

EXTERN_C void 
xs_init(pTHX) 
{ 
char *file = __FILE__; 
/* DynaLoader is a special case */ 
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
} 

static void
    PerlPower(char * arg[], int taille)
    {
	
      dSP;                
   int count = 0, i = 0, j=0;
   char *clef;
  SV *value;
  SV *tmp;
  I32 taille_tab;
  I32 iter;
  I32 Lcle = 0;
  HE *curseur;
  AV *tab;
  HV *hash;


      ENTER;      
      SAVETMPS;                
      PUSHMARK(SP);      

      while( i < taille )
          XPUSHs(sv_2mortal(newSVpv(arg[i++],0))); 

      PUTBACK; 
      count = perl_call_pv("lance", G_ARRAY);  
      SPAGAIN;      
                                      
      if(count != 0) {
         printf("Nombre de retour = %d\n",count);

        tab = (AV *) SvRV(POPs);  
		

       taille_tab = av_len(tab);
       printf("taille = %d\n",taille_tab+1);

       i=0;
       while( i <= taille_tab )
      {
          tmp = *av_fetch(tab, i, 0);
          if( SvTYPE(SvRV(tmp)) == SVt_NV )
              printf("Entier\n");
          else if( SvTYPE(SvRV(tmp)) == SVt_PVAV ){

              printf("Ligne %d :\n",i+1);

              hash = (HV *) SvRV(tmp);
              iter = hv_iterinit(hash);
              for(j=0;j<iter;j++)
             { 
                  curseur = hv_iternext(hash);
                  clef = HePV( curseur, Lcle);
                  value = HeVAL( curseur );
                 printf("Champ = %s  Valeur = %s Taille du champ = % 
                                      d\n",clef,SvRV(value),Lcle);
			
             }
        }			
        i++;
      }
	
      PUTBACK;
      FREETMPS;    
      LEAVE;					
}

int main (int argc, char **argv, char **env)
{
    char *user = "root";
    char *pwd = "";
    char *base = "questionnaire";
    char *driver = "mysql";
    char *args[] = { driver, base, user, pwd, "insert into question values ('','machin','','','','')", "delete from question" };
    char *embedding[] = { "", "Bidon.pm" };
    time_t deb, fin;
    int arg = 2;

    time(&deb);

    my_perl = perl_alloc();
    perl_construct(my_perl);
    perl_parse(my_perl, xs_init, arg, embedding, NULL);
	
    PerlPower(args,sizeof(args) / sizeof(args[0]));
    
    perl_destruct(my_perl);
    perl_free(my_perl);

    time(&fin);
    printf("Temp execution = %d secondes\n",fin-deb);
}


Voilà, merci encore pour tout !
:D
0