Bienvenue sur le forum !

Si vous souhaitez rejoindre la communauté, cliquez sur l'un de ces boutons !

Qt 5 : 5.8.0 - Qt Creator : 4.2.2 - Qt Installer : 2.0.3 - JOM : 1.1.2 - Qt Build suite : 1.7.0 - VS Qt 5 : 2.0.0

[Qt4] Reconnaissance d'encodage

Salut !

Je cherche depuis peu à trouver une api permettant de faire de la reconnaissance d'encodage (en C++). J'ai trouvé quelques pistes que voici :
- utrac une application/librairie qui ne semble plus être maintenu depuis 2005, et qui malheureusement est encore bugée,
- la commande unix file qui marche bien (mais que j'ai beaucoup de mal à compiler sous mon ordi - en windows : dépendance de python que je ne connais pas du tout),
- la fonction Qt (juste ce qu'il me fallait :)) codecForContent. Malheureusement elle à disparu avec Qt4 :/ (détail de codecForContent dans la doc Qt 3.3).

J'ai également cru comprendre que Kde avait implémenté quelque chose de similaire (basé sur la commande file), mais je n'arrive pas à trouver comment utiliser la chose :/. J'ai trouvé des infos sur le site de kde mais ils indiquent que cette utilisation est déprécié, et qu'il faut maintenant utiliser findByContent, malheureusement je ne vois pas comment reconnaitre l'encodage du fichier avec la classe KMimeType.

Donc mes questions sont les suivantes :
- est ce que vous connaissez une librairie (ou autre) permettant de reconnaitre l'encodage d'un texte ?
- savez vous si la commande unix file est utilisable en tant que librairie ou comment "l'exporter en librairie" ?
- avez vous compris comment utiliser KMimeType afin de reconnaitre l'encodage ?
- savez vous si Trolltech à remplacé la fonction codecForContent ou s'il la bel et bien supprimé (a priori il l'a supprimé, mais j'ai peu être mal compris) ?

Merci d'avance pour vos réponses.

Réponses

  • December 2007 modifié
    Un exemple tout bete pourquoi il ne faut pas se fier aux fonctions qui de ce genre:
    - ouvrir notepad
    - ecrire: "this app will break" (sans les ")
    - sauvegarder/fermer
    - ouvrir

    Tu vois ce que je vois?

    Voila pourquoi TT a vire cette fonctionnalite: elle n'est pas assez precise. Bien que l'exemple ne soit pas lie a Qt, je pense que tu comprends la problematique.

    Apres, je ne peux pas repondre a tes questions car je n'ai pas la reponse, mais si tu choisit d'utiliser une de ses fonctions/librairies/etc. ne sois pas etonne si un jour tu te retrouves avec du charabia.

    Bonne chance
  • December 2007 modifié
    rumpl said:
    Un exemple tout bete pourquoi il ne faut pas se fier aux fonctions qui de ce genre:
    - ouvrir notepad
    - ecrire: "this app will break" (sans les ")
    - sauvegarder/fermer
    - ouvrir

    Tu vois ce que je vois?
    Non désolé je ne vois pas, je suis sous vista, et à priori il ont dut fixer ce bug qui à l'air connu. Je me suis renseigné sur ce site qui parlait du "this app will break".

    Merci pour l'avertissement, j'étais déjà au courant qu'il y a des cas ou la reconnaissance ne marche pas. On peut le remarquer par exemple grâce à la doc de Qt3.3 qui parle de probabilités et d'heuristiques.
    Maintenant si cela peut marcher dans certains cas, cela sera toujours mieux que d'ouvrir avec le mauvais encodage.

    J'essai toujours de compiler les sources de la commande file sous windows, mais je n'y arrive pas, j'ai une erreur que je ne comprend pas :
    In file included from 3rdparty\file-4.17\src\apprentice.c:34:
    c:/MinGW/include/stdlib.h:319: error: conflicting types for 'strtol'
    c:/MinGW/include/stdlib.h:318: error: previous declaration of 'strtol' was here
    c:/MinGW/include/stdlib.h:319: error: conflicting types for 'strtol'
    c:/MinGW/include/stdlib.h:318: error: previous declaration of 'strtol' was here
    Voila les lignes correspondantes (318 et 319) dans le fichier stdlib.h :
    _CRTIMP long __cdecl    strtol    (const char*, char**, int);
    _CRTIMP unsigned long __cdecl strtoul (const char*, char**, int);
    Je ne comprend pas le problème, les deux fonctions ont des noms différents !? Quelqu'un aurait une idée ?
    Quelqu'un d'autre à déjà eu un problème similaire au mien, mais il semble avoir fait son propre makefile (pour ma part j'ai utilisé qmake).
    rumpl said:
    Bonne chance
    Merci :D
  • Adrien13 said:
    Je ne comprend pas le problème, les deux fonctions ont des noms différents !? Quelqu'un aurait une idée ?
    Quelqu'un d'autre à déjà eu un problème similaire au mien, mais il semble avoir fait son propre makefile (pour ma part j'ai utilisé qmake).
    C'est erreurs veulent tout simplement dire que ces fonctions sont définis quelque part dans les includes de ton mingw, en l'occurence dans stdlib.h
  • chsxf said:
    C'est erreurs veulent tout simplement dire que ces fonctions sont définis quelque part dans les includes de ton mingw, en l'occurence dans stdlib.h
    Merci pour la réponse.
    Ou est l'erreur alors ? Tu veux dire que ce n'est pas normal qu'elles soient définies à cet endroit ? Comment faire alors pour pouvoir compiler ?
  • Non, ce que je veux dire, c'est que la fonction strtol est définie par stdlib.h de mingw et que apprentice.c de file semble vouloir la redéfinir !
  • Non ce n'est pas le cas, apprentice.c ne fait que les utiliser.
    En fait il inclue stdlib.h à la ligne 34 :
    #include <stdlib.h>
    Ce qui est très bizarre c'est qu'on dirait qu'il confond le nom des fonctions il qu'il croit qu'elles s'appellent toutes les deux strtol.

    Sinon j'ai un peu avancé : en fouillant sur le site de debian, je me suis apercu qu'il y avait marqué ceci :
    À partir de la version 4, la commande file n'est ni plus ni moins qu'un encapsulateur de la bibliothèque « magic ».
    Je me sert donc de la librairie magic que je télécharge déjà compilée, ce qui me facilite la tâche.
    J'ai un dernier soucis à régler, je déposerai ensuite les sources pour ceux que ca intéresse.

    Je veux faire une librairie en Qt qui encapsule la librairie magic (arrêtez moi si ce n'est pas une bonne idée, ou si ce n'est pas possible : je n'ai jamais fait de librairie).
    Voila mon fichier pro :
    TEMPLATE = lib

    DESTDIR = ..\..\lib
    TARGET = encodingTool
    DEPENDPATH += . 3rdparty/libmagic
    INCLUDEPATH += . 3rdparty/libmagic

    # Input
    HEADERS += FileTypeInfo.h 3rdparty/libmagic/magic.h
    SOURCES += FileTypeInfo.cpp

    LIBS += -L3rdparty/libmagic -lmagic
    La compilation se passe bien jusqu'à la création de la librairie. Voila la sortie console :
    g++ -c -O2 -frtti -fexceptions -mthreads -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"c:\Qt\4.3.2\include\QtCore" -I"c:\Qt\4.3.2\include\QtCore" -I"c:\Qt\4.3.2\include\QtGui" -I"c:\Qt\4.3.2\include\QtGui" -I"c:\Qt\4.3.2\include" -I"." -I"3rdparty\libmagic" -I"c:\Qt\4.3.2\include\ActiveQt" -I"release" -I"." -I"c:\Qt\4.3.2\mkspecs\default" -o release\FileTypeInfo.o FileTypeInfo.cpp
    g++ -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -mthreads -Wl -shared -Wl,--out-implib,..\..\lib\libencodingTool.a -o "..\..\lib\encodingTool.dll" release\FileTypeInfo.o -L"c:\Qt\4.3.2\lib" -L3rdparty/libmagic -lmagic -lQtGui4 -lQtCore4
    Creating library file: ..\..\lib\libencodingTool.a
    release\FileTypeInfo.o(.text+0x58):FileTypeInfo.cpp: undefined reference to `magic_open'
    release\FileTypeInfo.o(.text+0xa3):FileTypeInfo.cpp: undefined reference to `magic_load'
    release\FileTypeInfo.o(.text+0x193):FileTypeInfo.cpp: undefined reference to `magic_error'
    release\FileTypeInfo.o(.text+0x2bc):FileTypeInfo.cpp: undefined reference to `magic_file'
    collect2: ld returned 1 exit status
    Si je met en commentaire tout le code qui utilise la librairie magic, la compilation se termine bien.
    Est ce que j'ai oublié quelque chose dans mon fichier pro ?
  • il semble qu'il manque une librairie

    si mingw fournit une commande nm, essaie
    nm une_librairie.lib
    sur les librairies dont tu dispose pour trouver où sont définis magic_open ...

    et ajoute cette librairie à ton .pro
  • Voila ce que donne (en partie) un nm sur libmagic.a :
    00000000 T magic_error
    000001d0 T magic_file
    00000570 T magic_load
    000000c0 T magic_open
    et sur FileTypeInfo.o :
    U _magic_error
    U _magic_file
    U _magic_load
    U _magic_open
    Je ne connais pas la commande nm, mais je dirais que tout est présent :/.
  • Je suppose que le fichier libmagic.a se trouve bien dans 3rdparty/libmagic ?
  • Oui c'est le cas.
    Je viens de tester une autre chose : créer un programme qui contient une classe FileTypeInfo et qui utilise la librairie magic. Le résultat de l'édition de liens et le même que si je créait une librairie perso qui surcharge libmagic.
    J'espère être bien clair dans mes explications :/.
  • Le fichier que tu as mis en lien est un paquet debian.
    Je ne suis pas du tout certain de ce que je vais dire mais il me semblerait logique de ne pas pouvoir utiliser un .a d'une lib linux directement comme ça sous windows, même avec mingw.
  • Adrien13 said:
    Voila ce que donne (en partie) un nm sur libmagic.a :
    00000000 T magic_error
    000001d0 T magic_file
    00000570 T magic_load
    000000c0 T magic_open
    et sur FileTypeInfo.o :
    [quote]U _magic_error
    U _magic_file
    U _magic_load
    U _magic_open
    Je ne connais pas la commande nm, mais je dirais que tout est présent :/.[/quote]
    _magic_file dans FileTypeInfo.o
    magic_file dans libmagic.a
    ...
    ça ne me semble pas très bon!
    je pense à un préfixe '_' rajouté par le compilateur, mais je ne connait pas très bien la compil avec mingw

    ps: nm liste les symboles présents dans un objet ou une librairie
  • Il me semble qu'une librairie est réutilisable d'un système à l'autre, mais peut être je me trompe.
    Je vais tester sous un linux pour voir si ca marche ou pas.
  • chsxf said:
    Le fichier que tu as mis en lien est un paquet debian.
    Je ne suis pas du tout certain de ce que je vais dire mais il me semblerait logique de ne pas pouvoir utiliser un .a d'une lib linux directement comme ça sous windows, même avec mingw.
    je dirais même plus, je serais épaté que ça marche!
  • En fait je n'ai pas de quoi tester sous linux maintenant. Je vais alors revenir à la compilation des sources de debian puisque vous êtes deux à me dire que la librairie n'est pas portable.
    Mais je ne vois toujours pas comment résoudre l'erreur de compilation qui apparaissait dans stdlib.h avec strtol :/.
  • December 2007 modifié
    si tu compiles avec mingw, les includes mingw doivent être prioritaires sur ceux de windows

    je ne peux pas t'en dire plus, je suis sur Linux, mais il me semble que le problème se situe là

    vérifie l'ordre des directives de compilation -I
  • J'ai réussi à compiler un peu plus loin. En fait le problème avec strtol et stddef (plus de détail à la fin de ce post) venait du fait que normalement pour être compilée, la commande unix file (petit récapitulatif ici : file) devait utiliser un script configure. Je me suis aperçu qu'il définissait un fichier config.h qui déclarait un certain nombre de macros. Je l'ai donc recopié et configuré à la mano.

    Maintenant la compilation plante sur des fonctions ou headers qui ne sont pas inclus dans MinGW. J'ai un peu lu la page de wikipédia sur MinGW (le compilateur que j'utilise) et en fait j'ai compris que MinGW n'incluait pas un certain nombre de fonctions contrairement à CygWin afin notamment de garantir de meilleures performances. A priori j'aurai la possibilité avec CygWin de compiler la librairie magic, puisqu'il me fournirait les headers manquant.

    Ma question est celle d'un débutant sous CygWin : est ce que mon application sera ensuite portable sur d'autres machines windows qui n'aurait pas CygWin ? Je pense que oui tout comme MinGW, mais je n'en suis pas sur. J'ai cru comprendre que CygWin utilisait des dll pour cela.

    Merci pour vos réponses.
  • J'ai réussi à tout compiler :
    - la librairie magic sous cygwin avec configure && make
    - mon application (sous mingw) qui utilise la librairie magic que j'ai compilé

    La compilation se passe nickel, mais au moment de l'exécution : "l'application a cessée de fonctionner..." et aucun message dans la console.
    C'est parceque je mélange du cygwin et du mingw ? Ce n'est pas fesable ?

    Si je compile tout avec Cygwin, ca passe et le résultat est nickel.
    Seulement j'aimerai continuer à compiler avec MinGW, je le trouve très pratique, léger et puis il est bien intégré par Qt, ce qui n'est pas le cas de Cygwin.
  • As-tu passé ton application dans un débuggeur pour voir où était le plantage ?

    J'avais essayé Cygwin il y a quelques années mais à 600 Mo l'installation, j'ai décidé de m'orienter vers MinGW. Cependant Cygwin n'est pas réputé pour être très "ouvert" à l'interopérabilité mais je ne sais pas dans quelle mesure il pourrait empêcher ce que tu essaies de faire.
  • Adrien13 said:
    La compilation se passe nickel, mais au moment de l'exécution : "l'application a cessée de fonctionner..." et aucun message dans la console.
    C'est parceque je mélange du cygwin et du mingw ? Ce n'est pas fesable ?
    Si je compile tout avec Cygwin, ca passe et le résultat est nickel.
    bien possible que les formats d'objets ne soient pas compatibles
  • Merci pour vos réponses.
    Non je n'ai pas essayé de debuger par manque de temps. Je le ferai des que possible, et je vous tiendrais au courant.
    chsxf said:
    J'avais essayé Cygwin il y a quelques années mais à 600 Mo l'installation, j'ai décidé de m'orienter vers MinGW. Cependant Cygwin n'est pas réputé pour être très "ouvert" à l'interopérabilité mais je ne sais pas dans quelle mesure il pourrait empêcher ce que tu essaies de faire.
    Le tout une fois installé tiens sur 2 ou 3 giga ce qui est plutôt lourd. Cygwin permet de faire beaucoup de choses issues de linux, mais c'est beaucoup trop lourd pour la plupart des applications à mon gout. Je préfere largement MinGW.
    Nicolas SOUCHON said:
    bien possible que les formats d'objets ne soient pas compatibles
    C'est bien ce que je crains :/.
Connectez-vous ou Inscrivez-vous pour répondre.