IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

lecture binaire sur un flux


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Par défaut lecture binaire sur un flux
    Salut à tous.
    Voila, je dois faire des lectures binaires sur un flux de la stl. Pour cela, je commence par l'ouvrir en binaire puis j'utilise une fonction pour lire les données au fur et à mesure. J'ai mis au point deux versions de cette fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    	int yaread(struct SDL_RWops *context, void *ptr, int size, int maxnum) {
    		std::istream* s = (std::istream*)context->hidden.unknown.data1;
    		int taille=0;
    		while(!s->eof() && taille<size*maxnum) {
    			((char*)ptr)[taille] = s->get();
    			taille++;
    		}
    		return taille/size;
    	}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	int yaread(struct SDL_RWops *context, void *ptr, int size, int maxnum) {
    		std::istream* s = (std::istream*)context->hidden.unknown.data1;
    		int beg = s->tellg();
    		s->seekg(0,ios::end);
    		int end = s->tellg();
    		s->seekg(beg,ios::beg);
    		int taille = size*maxnum<=end-beg?size*maxnum:end-beg;
    		s->read((char*)ptr,taille);
    		return taille/size;
    	}
    Ne vous préoccupez pas trop des deux premières lignes ni de la valeur de retour, cette fonction est appellée par une bibliothèque qui n'est pas de moi.
    Il faut savoir que ces deux versions fonctionnent, j'arrive à charger correctement mon image (parceque c'est une image) et à l'afficher. Ensuite, l'objet contenant cette fonction est détruit, le flux est fermé et mon programme continue son exécution (c'est un jeu de société, ca peut prendre longtemps).
    Le problème est que si j'utilise la version numéro 2 de cette fonction, le destructeur du flux provoque un plantage en accédant à une portion de mémoire invalide (je rapelle que ce destructeur est appelé longtemps après l'exécution de ma fonction.
    Je pourrais bien sur n'utiliser que la première version de cette fonction, mais elle est incroyablement lente (forcément, si on lit les octets un à un...).

    Quelqu'un verrait-il ou est l'erreur? J'utilise visual studio 2005.

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Le stream est bien en binaire? Je ne sais plus trop sur quelle plate-forme ou avec quelle version, mais il me semble que certaines classes de stream ont des problèmes avec seekg()/tellg() quand elles sont ouvertes en mode texte...

    Et aussi, je ne suis pas certain de la priorité du ?: et du >=, tu devrais peut-être t'en assurer avec des parenthèses...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Par défaut
    Non non, rien à voir avec ca.
    Je dis bien que ces deux implémentations fonctionnent parfaitement. D'ailleurs la portion de code servant à vérifier si je ne suis pas arrivé à la fin de mon fichier ne sert quasiment à rien puisque je peux constater avec un peu de logging que la bibliothèque appelant ces fonctions ne demande jamais plus que la taille du fichier (c'est une biblio de lecture de JPG, je suppose qu'il est marqué quelquepart au début du fichier la taille qu'il fait).
    Le seul problème est que la seconde implémentation semble "déteriorer" le flux. Ce qui fait qu'à sa destruction (qui se produit longtemps après sa fermeture) son destructeur va causer un plantage.

    Edit: ca vient justement de me donner une petite idée. J'ai viré cette fameuse partie du code et visiblement le résultat est exactement le même. On dirait que c'est la fonction read() qui pose problème.

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Par défaut
    Ca va, je crois avoir trouvé une solution. Ma

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Par défaut
    Ca va, je crois avoir trouvé une solution. Ma fonction est devenue:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	int yaread(struct SDL_RWops *context, void *ptr, int size, int maxnum) {
    		std::istream* s = (std::istream*)context->hidden.unknown.data1;
     
    		return s->rdbuf()->sgetn((char*)ptr,size*maxnum)/size;
    	}
    En plus, contrairement à istream.read() je recois directement le nombre de bytes lus. Par contre il me semble que j'avais déja eu des problèmes avec certaines implémentations de la stl qui ne permettaient pas de récupérer un pointeur le buffer. Enfin, je verrais bien quand je testerais sous gcc.

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Par défaut
    Et m***, ca cesse de fonctionner dés que je compile en mode release. Je commence à en vouloir à visual studio la

  7. #7
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    Plus simple que ton dernier truc, tu as std::istream::readsome(), non ?
    Je suis sceptique sur ta première fonction, à cause du eof qui intervient avant le get(), soit trop tard.

    Sinon, il n'y a pas de problèmes de mélanges de reinterpret_cast alors que tu es en plein héritage, possiblement multiple (si std::fstream, sans o ni i) ? Utilises-tu la bonne vtable ? -> si tu affiches la valeur du pointeur sur std::istream avant et après obsfuscation via un void* (si je comprends bien).

    Evidemment, il faut s'assurer que le type du pointeur officiellement stocké soit réutilisé avant utilisation, et pas un autre.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

Discussions similaires

  1. flux binaires sur RS232
    Par Tymk dans le forum C++
    Réponses: 8
    Dernier message: 13/07/2008, 01h17
  2. lecture & ecriture sur le port serie
    Par anouar dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 08/07/2005, 17h15
  3. Lecture / écriture sur un port com
    Par dorian833 dans le forum C++
    Réponses: 7
    Dernier message: 07/07/2005, 15h20
  4. [Stratégie] Lecture ponctuelle d'un flux continu
    Par christopheJ dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 30/07/2004, 16h30
  5. [Servlet][Deb]envoyer image gif sur le flux http
    Par ptitBoutchou dans le forum Servlets/JSP
    Réponses: 15
    Dernier message: 09/04/2004, 10h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo