Transcription Perl/C++ [Résolu]

Messages postés
13
Date d'inscription
mardi 29 juin 2010
Statut
Membre
Dernière intervention
30 juin 2010
- - Dernière réponse : dreddfullmetal
Messages postés
13
Date d'inscription
mardi 29 juin 2010
Statut
Membre
Dernière intervention
30 juin 2010
- 30 juin 2010 à 17:45
Salut à tous :)
Je reviens à la charge aujourd'hui car je suis encore bloqué sur le projet de mon stage :p

alors je dois transcrire une fonction perl qui Permet de créer un message pour aller chercher les informations que j'ai besoin.

Je te met le code en Perl :

sub mkmsg ($@) {
# makes a message with the items in the given array as questions
my ($dst, @questions) = @_;

my $src = 'FB';
$dst = sprintf('%02X', $dst);
my $len = '00';
my $cs = '0000';
my $msg = "64:" . join(';', @questions);

$len = length("{$src;$dst;$len|$msg|$cs}");
$len = sprintf("%02X", $len);

$cs = checksum16("$src;$dst;$len|$msg|");
$cs = sprintf("%04X", $cs);
return "{$src;$dst;$len|$msg|$cs}";
}


Alors les questions que je me pose et que j'arrive pas a trouver sur le net sont :
-Qu'est ce que le $@ qui est en paramètre d'entrée de la fonction et comment le manipuler.

-Comment retranscrire l'initialisation de la 1ere variable
my ($dst, @questions) = @_;

-je comprend rien a la 5eme variable, on dirait un appel de fonction mais l'écriture est vraiment bizarre :
my $msg = "64:" . join(';', @questions)

Voila Je vous remercie a l'avance si vous pouvez m'éclairer sur le sujet et pour le temps consacré.

Cordialement,
Dredd


Avoir le refrain beau a rechercher des crosses....serait prendre a rever la haine a écoper...
Afficher la suite 

Votre réponse

9 réponses

Meilleure réponse
Messages postés
3832
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
3 avril 2019
163
3
Merci
Ne connaissant pas le Perl, je vais t'expliquer ma démarche pour comprendre le code. Néanmoins, si tu pouvais ajouter un exemple d'utilisation de cette fonction, ça aiderait à comprendre son utilité (je n'arrive pas à lancer ton exemple, j'ai une erreur de syntaxe).
J'ai d'abord regardé la FAQ Perl: http://perl.developpez.com/faq/perl/?page=sectionB
Ensuite, j'ai lu le code et j'ai cherché tout les signes que je ne comprenais pas.

-Qu'est ce que le $@ qui est en paramètre d'entrée de la fonction et comment le manipuler.

Il semble que c'est une variable qui contient le dernier code d'erreur. Ce qui est assez bizarre.
http://www.kichwa.com/quik_ref/spec_variables.html
http://affy.blogspot.com/p5be/ch12.htm

-Comment retranscrire l'initialisation de la 1ere variable
my ($dst, @questions) = @_;

Je n'ai pas trouvé la signification de @_, mais je pense qu'il y a découpage automatique d'un tableau en variable.

-je comprend rien a la 5eme variable, on dirait un appel de fonction mais l'écriture est vraiment bizarre :
my $msg = "64:" . join(';', @questions)

Si j'ai bien compris, on prend la chaîne "64:" on prend le tableau "questions" et on le transforme en une seul chaine de caractère séparé par des ";". Puis on concatène "64:" et la chaîne obtenu.

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 111 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cptpingu
Messages postés
3832
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
3 avril 2019
163
3
Merci
Après un peu de réflexion, je pense avoir compris le but de ce code.
Le $@ semble vouloir dire "accepte une infinité d'arguments" et le @_ prendre tous les arguments.
Ensuite lors de la découpe: "my ($dst, @questions) = @_;", on prend le premier argument et on le met dans "dst", et tous le reste dans un tableau "questions".
Après le reste, c'est facile, c'est juste du formattage de donnée.
#!/usr/bin/perl -w

sub checksum16 ($) {
# calculates the checksum 16
# of the given string argument
    my @bytes = unpack("C*", $_[0]);
    my $sum = 0;
    foreach(@bytes) {
$sum += $_;
$sum %= 2**16;
    }
    return $sum;
}

sub mkmsg($@) {
    my ($dst, @questions) = @_;

    my $src = 'FB';
    $dst = sprintf('%02X', $dst);

    my $len = '00';
    my $cs = '0000';
    my $msg = "64:" . join(';', @questions);

    $len = length("{$src;$dst;$len|$msg|$cs}");
    $len = sprintf("%02X", $len);

    $cs = checksum16("$src;$dst;$len|$msg|");
    $cs = sprintf("%04X", $cs);

    return "{$src;$dst;$len|$msg|$cs}";
}

my $V_MSG = mkmsg("255", "cmd", "rte");

print $V_MSG."\n"


En voici une traduction en C++:
#include 
#include <sstream>
#include 

unsigned int checksum16(const std::string& s)
{
  unsigned int sum = 0;
  const unsigned int size = s.size();
  for (unsigned int i = 0; i < size; ++i)
  {
    sum += s[i];
    sum %= 2 << 15;
  }

  return sum;
}

std::string toStringHex(unsigned int nb, int size)
{
  std::ostringstream buff;
  buff << std::setw(size) << std::setfill('0')
       << std::uppercase << std::hex << nb;
  return buff.str();
}

std::string computeMsg(const char* questions[])
{
  std::ostringstream buff;
  bool first = true;

  buff << "64:";
  while (questions && *questions)
  {
    if (!first)
      buff << ";";
    else
      first = false;
    buff << *questions;
    ++questions;
  }

  return buff.str();
}

std::string mkmsg(unsigned int idst, const char* questions[])
{
  std::ostringstream buff;

  const std::string src = "FB";
  const std::string dst = toStringHex(idst, 2);
  const std::string msg = computeMsg(questions);

  buff << "{" << src << ";" << dst << ";00|"
       << msg << "|0000}";
  const std::string len = toStringHex(buff.str().size(), 2);

  buff.str("");
  buff << src << ";" << dst << ";"<< len << "|"
       << msg << "|";
  const std::string cs = toStringHex(checksum16(buff.str()), 4);

  buff.str("");
  buff << "{" << src << ";" << dst << ";"
       << len << "|" << msg << "|" << cs << "}";

  return buff.str();
}

int main()
{
  const char* tab[] = {"cmd", "rte"};
  std::cout << mkmsg(255, tab) << std::endl;

  return 0;
}


_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 111 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cptpingu
Messages postés
3832
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
3 avril 2019
163
3
Merci
toStringHex

Transforme une entier en une réprésentation héxadécimal de celui-ci, sous forme de chaîne de caractère.
Ex: 42 => "2A", 255 => "FF"

Je comprend pas comment tu arrive a retourner un truc que tu n'a pas déclaré

Je n'ai pas compris ta question, tout est déclaré.

De plus la fonction int main() serait l'équivalent de la fonction getsparam() en Perl ?:p

Ce n'est pas un équivalent, mais deux systèmes différents pour récupérer les mêmes informations.
En C ou C++, on passe les arguments de la ligne de commande via argc et argv du main. C'est à dire que argc et argv sont automatiquement remplis.
En perl, il faut appeler une fonction spécifique pour faire ce travail.

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 111 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cptpingu
Messages postés
3832
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
3 avril 2019
163
3
Merci
Heu... J'ai précisé que je ne sais pas du tout faire de Perl :p
Je vais essayer de déduire quelques trucs, mais je suis aux limites de ce que je peux faire.

sub waitfor ($$)

$$ apparament c'est comme en script shell, ça prend le pid courant (numéro de processus)


my ($H, $timeout) = @_;
my $rin = '';

Après il essaie de déclencher un timer, afin de ne pas regarder trop souvent le flux (ce qui pourrait saturer la machine).

vec($rin, fileno($H), 1) = 1;

Vec permet de récupérer un set de bit. Le troisième argument semble servir à donner la taille du champs de bit. Ici elle est de 1, donc on récupère un et un seul bit. Il met donc le bit à 1 dans $rin.

my $found = select($rin, undef, undef, $timeout);

Apparamment, select récupère un file descriptor. Donc cette ligne permet de récupérer la main sur un flux, dès que celui-ci est prêt en vérifiant avec un delai de "$timeout"

sysread($H, $buf, $len-length($buf), length($buf));

Ça semble corresponde à "read", et donc ça revient à tenter de lire sur un flux.

Voilà, je ne peux pas t'aider plus :)
Effectivement, je ne peux que te conseiller de parler à ton responsable, car cette tâche est assez hardu sans connaissances avancées en Perl.

________________________________________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée quand un post répond à votre question

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 111 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cptpingu
Messages postés
13
Date d'inscription
mardi 29 juin 2010
Statut
Membre
Dernière intervention
30 juin 2010
0
Merci
Elle est utilisée ici dans le Code, au moment ou le code va chercher les informations sur un Onduleur.


#
# Read Param from SolarMax...
#
sub getsmparam ($$$$$) {
my ($P_HANDLE, $P_TIMEOUT, $P_DEVADDR, $P_DEBUG, $P_COMMAND) = @_;
 
   	my $V_MSG = mkmsg($P_DEVADDR, $P_COMMAND->{name});
.....
le code continue je n'ai pas tout mis

Je vais allez visité les sites que tu a mis

Cordialement,
Dredd


Avoir le refrain beau a rechercher des crosses....serait prendre a rever la haine a écoper...
Commenter la réponse de dreddfullmetal
Messages postés
13
Date d'inscription
mardi 29 juin 2010
Statut
Membre
Dernière intervention
30 juin 2010
0
Merci
Oua :p tu es vraiment impressionnant :p

Par contre, je n'ai pas trop compris a quoi servait la fonction toStringHex et je comprend pas comment tu arrive a retourner un truc que tu n'a pas déclaré :p
De plus la fonction int main() serait l'équivalent de la fonction getsparam() en Perl ?:p

Merci de prendre du temps pour moi et de faire ca aussi bien :)

Cordialement,
Dredd


Avoir le refrain beau a rechercher des crosses....serait prendre a rever la haine a écoper...
Commenter la réponse de dreddfullmetal
Messages postés
13
Date d'inscription
mardi 29 juin 2010
Statut
Membre
Dernière intervention
30 juin 2010
0
Merci
A oui je viens de vérifier, c'est le .str qui me gêné mais il est bien déclaré :p

En tout cas je te remercie vraiment :p
je comprend pas tout le code car j'ai pas vraiment le niveau mais je vais bosser dessus :)

Je vais prendre exemple sur ce qui tu as fait pour faire les fonctions restantes, je les posterais dans la journée ou demain :p je suis pas aussi rapide que toi :p

Cordialement,
Dredd


Avoir le refrain beau a rechercher des crosses....serait prendre a rever la haine a écoper...
Commenter la réponse de dreddfullmetal
Messages postés
13
Date d'inscription
mardi 29 juin 2010
Statut
Membre
Dernière intervention
30 juin 2010
0
Merci
Me revoila :p

Malgré mes efforts et mes recherches, j'ai l'impression que plus ca va plus ca se complique xD :o

Dans la fonction que je dois transcrire il y a une fonction vec que je n'arrive pas a utiliser
Je te met le code pour que tu voie ce que c'est.
sub waitfor ($$) 
{
# waits until $_[0] becomes readable
# timeout after $_[1] seconds
my ($H, $timeout) = @_;
my $rin = '';
vec($rin, fileno($H), 1) = 1;
my $found = select($rin, undef, undef, $timeout);	
# block until readable
return $found;
}


Je te met aussi celle d'après ou je comprend pas le sysread :o

sub tryread ($$$) {
# tries hard to read $_[1] bytes from $_[0]
# timeout is $_[3];
# returns the result
my ($H, $len, $timeout) = @_;
my $buf = '';
while( length($buf) < $len ) {
# wait for something to happen
if( ! waitfor($H, $timeout) ) {
print "Timeout\n";
return undef;
}
my $rv = sysread($H, $buf, $len-length($buf), length($buf));	# read the remaining bytes and put it in buf at the correct place
if( !defined($rv) ) {
die "Error reading: $!";
}
#print "read $rv bytes: $buf\n";
}
return $buf;
}


Je te remercie pour ce que tu as déjà fait
et je vais dire a mon tuteur dès que je le verrais que c'est vraiment pas de mon niveau

Si tu peux m'éclairer sur la chose, je t'en serais vraiment reconnaissant :)

Cordialement,
Dredd

Avoir le refrain beau a rechercher des crosses....serait prendre a rever la haine a écoper...
Commenter la réponse de dreddfullmetal
Messages postés
13
Date d'inscription
mardi 29 juin 2010
Statut
Membre
Dernière intervention
30 juin 2010
0
Merci
Je te remercie en tout cas pour tout le temps passé et toutes les explications que tu as pu me fournir :)

Cela m'aide déjà a un peu mieu comprendre le code même si je pense que je ne comprendrais pas les subtilités avant un pti moment :p

Bonne fin de journée a toi et bonne continuation

et encore Merci :)

Cordialement,
Dredd


Avoir le refrain beau a rechercher des crosses....serait prendre a rever la haine a écoper...
Commenter la réponse de dreddfullmetal

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.