Mon get ou mon put avec for binary retransforme mes string PROBLEME UNICODE ? ! [Résolu]

Signaler
Messages postés
130
Date d'inscription
dimanche 16 décembre 2007
Statut
Membre
Dernière intervention
28 janvier 2013
-
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
-
Hooolalal, dans quoi je me suis fourré encore
Bonjours avant tout, et un snifff au secour ....
je suis MEGA BLOQUE depuis 1 semaine, mais j'ai réussie à être au plus prêt du bug !

alors sans vous donner mes 3 milliards de lignes de code voilà mon problème

je suis sur une compression simple d'une chaine de caractère, beaucoup plus rapide que ZLIB.DLL
elle est en .asm, mais c'est pas le soucie car elle fonctionne bien, et si j’aurais voulue la faire en basic j’aurais put avec copymemory et évidement strptr(ma_chaine$) faire pareil.
Et c'est peut être cela tout le problème car je travail dans le derrière le dos de VB sans rien lui demander
je m'explique :
un string dans VB c'est enregistrer en 16 bits, exemple :
a$="xavier" => "x a v i e r" ou plus exactement en octets "120,0,97,0,118,0,105,0,101,0,114,0"
donc pour compresser et décompresser je me suis basé sur le fait que je peut écrire sur le 1er octets, et je me contrefiche du 2ème !
jusque là tout allez mais j'ai eu des problème, alors j'ai du prendre en compte le 1er octets, et être sur de réécrire un 0 dans le 2ème, et là oui !
si je vous donne l'exemple de 126 fois le caractères au chiffre 151(oui au dessus de la table de 127)
ma dll ecrira "126,0,151,0" au lieu de "151,0,151,0,151,0,151,0...ETC."
mais ATTENTION,... si j'inserre cela en basic entre la compression et la décompression :

mem_BMP2$="126,0,151,0..........."
(les chiffre étant toujours l'octet donner par strptr(mem_BMP2$), c'est pour mieux comprendre)

fFile = FreeFile: Open chemin$ For Binary As #fFile
Put #fFile, , mem_BMP2$
Close #fFile
fFile = FreeFile: Open chemin$ For Binary As #fFile
mem_BMP2$ = String$(FileLen(chemin$), 0)
Get #fFile, , mem_BMP2$
Close #fFile

et là si je debug je remarque que : mem_BMP2$="126,0,63,0..........."
mon 151 c'est transformé en 63, le symbole "?" mais j'ai rien demander moi !
en faite plus exactement c'est cette ligne là " Get #fFile, , mem_BMP2$" qui recharge le code 151 en 63, sans cette ligne là cela n'arrive pas !
ou même si je fait a$=mem_BMP2$ au lieu de relire avec get
a$="126,0,151,0..........." j'ai bien mon 151 !
...
je sens,... je sais que cela à rapport avec l'UNICODE mais qu'est ce que je peut faire
...
je pourrait écrire mon fichier octets par octets ou le transférer dans un premier temps dans un un tableau byte, mais si je ne comprend pas le problème, j'ai peur que cela ne fonctionne pas bien non plus, et que si j'envoie cette chaine mem_BMP2$ par reseaux avec winsock que cela ce transforme aussi ?! .... je suis fatiguer, j'ai vraiment besoin d'aide là...
...
POURQUOI il y a cette transformation radicale du caractère juste avec
"Get #fFile, , mem_BMP2$"

12 réponses

Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
Salut

Excuse-moi, il est tard; je n'ai pas tout compris à ton histoire d'assembleur, de compression ...
Bref, tu sembles bien maitriser l'adressage mémoire.
Si tu cherches des infos : http://www.codeguru.com/vb/gen/vb_misc/algorithms/article.php/c7495/How-Visual-Basic-6-Stores-Data.htm et <là> sont très instructifs.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
234
Je me suis amusé à faire ceci, qui te montrera la "frontière", à travers une transposition en UFT-8 :
Option Explicit
Private Declare Function MultiByteToWideChar Lib "Kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long
Private Declare Function WideCharToMultiByte Lib "Kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, ByVal lpUsedDefaultChar As Long) As Long

Private Function vers_uft8(ByVal mon_car As String) As String
  Dim tampon As String, lLength As Long
  lLength = WideCharToMultiByte(65001, 0, StrPtr(mon_car), -1, 0, 0, 0, 0)
  tampon = Space$(lLength)
  lLength = WideCharToMultiByte(65001, 0, StrPtr(mon_car), -1, StrPtr(tampon), Len(tampon), 0, 0)
  tampon = StrConv(tampon, vbUnicode)
  vers_uft8 = Left$(tampon, lLength - 1)
End Function

Private Function lire_uft8(ByVal mon_car As String) As String
  Dim tampon As String, lLength As Long
  mon_car = StrConv(mon_car, vbFromUnicode)
  lLength = MultiByteToWideChar(65001, 0, StrPtr(mon_car), -1, 0, 0)
  tampon = Space$(lLength)
  lLength = MultiByteToWideChar(65001, 0, StrPtr(mon_car), -1, StrPtr(tampon), Len(tampon))
  lire_uft8 = Left$(tampon, lLength - 1)
End Function

Private Sub Command1_Click()
  Dim i As Integer, j As Integer, toto As String, titi As String, tata As String, cars As String, sep As String
  For i = 120 To 131 ' je prends cette fourchette exprès pour que tu voies mieux à partir d'où les choses diffèrent
   toto = Chr(i)
   titi = vers_uft8(toto)
   cars "": sep ""
   For j = 1 To Len(titi)
     If j > 1 Then sep = " + "
     cars = cars & sep & Asc(Mid(titi, j, 1))
   Next
   tata = Asc(lire_uft8(titi))
   MsgBox i & " " & cars & " " & tata
  Next
End Sub






________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
PS : Les chaines gérées par VB6, sont Unicode
Fonctions de conversion : StrConv
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
234
Bonjour, jack,
Je tiens à te remercier personnellement pour la communication de ces deux liens. Le second, en particulier, a apporté la réponse à une question que je me posais depuis longtemps. Je vais l'utiliser pour résoudre très différemment un problème (sans rapport avec celui du demandeur) que j'avais résolu de manière très ... "tarabiscotée". Merci.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
234
A rebixav,
J'ignore totalement les instructions que contient ta dll
Je remarque que le caractère 151 est compris dans l'intervalle 127-159 des caractères non nativement supportés par Windows. Comment ta dll les traduit-elle alors ? si c'est par un "?" ==>> tu as la raison de ton 63



________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Messages postés
130
Date d'inscription
dimanche 16 décembre 2007
Statut
Membre
Dernière intervention
28 janvier 2013

merci pour ces lien, que j'ai commencé à lire, ils ont l'air bien complet sur l'UNICODE, j'espère juste trouvé ma solution à mon problème !

pour expliquer plus brièvement mon problème :

la fonction chr$(151) ne donne pas = 151,0
mais 20,32
hors lorsque j'écrivais dans la mémoire je mettez 151,0, mais donc pas le chr$(151), son jumeau, "oui", car il s'affiche à l'écran pareil(je crois, je sais plus à force), mais lorsque l'on fait retour = a$=b$
si a$=chr$(151) et b$=Poke8(StrPtr(b$), 0,151)
retour redonne faux, pas vrai !

aprés une petite lecture de ton 2ème lien (il faut dire qu'il est un peu long)
je me suis amusé à écrire cela :

For i% = 0 To 255
b$ = Chr$(i%)
If PEEK8(StrPtr(b$), 0) > 127 Then Stop
If PEEK8(StrPtr(b$), 1) > 127 Then Stop
Next i%

et bien l'éditeur vb ne s’arrête pas avant que i% soit à 127,... oui je sdais cela paraissé évidement, mais pas pour moi vue que l'unicode ne redonne pas forcément le même chiffre
d'ailleur le chr$(128) ne m'as pas donné 128, mais 172 et 32 !
129= 129 et 0
131= 146 et 1
...ETC.

donc je vais devoir tout revoir et soit comprendre la transformation unicode pour la traduire, soit éviter de trop y toucher,...
merci !
Messages postés
130
Date d'inscription
dimanche 16 décembre 2007
Statut
Membre
Dernière intervention
28 janvier 2013

Après quelque heures de désespoir, de colère, de courage, de déception, et surtout de lecture au calme + une petite sieste de 1 heure, j'ai eu enfin le déclic que j’attends depuis une semaine
Bon faut dire qu'il y avais pas mal de défaut dans plusieurs procédure...
En faite si on veut travaillé avec des caractère sans ce préoccupé d'un problème de transformation, il faut surtout pas dépasser le caractère 127 ! donc dans ma compression j'ai éliminer :
cmp cl,255
par
cmp cl,127

pour enregistrer dans mon fichier de compression la taille du fichier de compression, je diviser par 256, alors que maintenant je divise bien sure par 128 !
...
et
cela marche !
évidement comme prévue plus rapide que la Zlib...
cela va en faire des super sources !
faut que je range, mais surtout que je fasse enfin des vrai test, et enfin de la ré-programmation qui avance au lieu de tourner en :
do
if trouve_bug=true then exit do
loop

car 48 heures de plus, je me serrais fait pizza TV pendant 1 mois
Messages postés
130
Date d'inscription
dimanche 16 décembre 2007
Statut
Membre
Dernière intervention
28 janvier 2013

Ben dis donc, je le garde au cas j'ai besoin un jour de travaillé l'unicode mais cela je vais pas le mettre dans mon .ASM cela rentre pas, et c'est pas très rapide, si je doit travaillé tout mes caractère comme cela ...

par contre je suis par curiosité entrain d'essayer d'accélérer la compression ZLIB, regarde ou j'en suis s'il te plait "ucfoutu" :

pas de compression : 50874=>50875 = 0.07s
ma compression : 50874=>8272 = 0.28s
la compression ZLIB level 1 : 50874=>5014 = 1.42s

comme tu voit je suis 5 fois plus rapide, c'est cool mais on peut peut-être améliorer ZLIB, regarde la procédure .BAS (compresse2 étant ZLIB.DLL) :

'---------------
If compresse_tempon_taille& <> l_ori& + (l_ori& * 0.01) + 12 Then
compresse_tempon_taille& = l_ori& + (l_ori& * 0.01) + 12
compresse_tempon_string$ = String(compresse_tempon_taille&, 0)
End If
lngCmpSize& = compresse_tempon_taille&
lngResult& = compress2(ByVal compresse_tempon_string$, lngCmpSize&, ByVal Text, l_ori&, CompressionLevel)
'---------------

Les deux points qui ralentissent sont :
- String(compresse_tempon_taille&, 0)
- et byval compresse_tempon_string$

la 1ère je m'en suis occupé, si on veut recompresser quelque chose de même taille pas besoin de recréer le fichier tempon (hummmm d'ailleurs il faut surtout qu'il soit d'une certainne taille, bref)

par contre je ne vois pas comment régler mon problème avec "byval" comment le remplacer, sans demander à VB de faire une copie énorme ?!
j'ai testé plus le fichier et gros plus c'est long à cause de byval, je sais j'avais ce problème sur la miènne alors j'ai utiliséer strptr(compresse_tempon_string$), mais zlib n'aime pas cela, il ne s'attend pas à tomber sur l'univers unicode ?!
...
dommage je suis content de ma compression, mais cela m'embête de laissé ZLIB si loin en terme de vitesse, comme tu la peut-être compris j'aimerais combiner cela mon besoin ma compression, et zlib, je serais le level 1, et zlib le level de 2à 10
... Et sur internet c'est tout le temps comme cela STRING=BYVAL
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
234
Le petit test montré n'était là que pour te montrer la frontière à partir de laquelle il te faudra écrire autrement.
Je ne me suis attelé qu'à la montrer du doigt.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
234
Je ne comprends par ailleurs pas ta démarche en ce qui concerne l'utilisation du passage ByVal.
Utiliser Byval, s'agissant de valeurs de type string, s'avère en fait assez souvent plus rapide qu'utiliser Byref. Cela dépend en fait du contexte. Tu trouveras sur le Web plusieurs déclarations dans ce sens faites après tests chronométrés.
Or, tu dis que la vitesse d'exécution est ton souci premier.
Sans préjudice du fait que Byval te permet de ne toucher à la valeur originale (l'écraser, donc) que lorsque telle est ta volonté.

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Messages postés
130
Date d'inscription
dimanche 16 décembre 2007
Statut
Membre
Dernière intervention
28 janvier 2013

heuuu... là c'est moi qui suit fatigué !

Tout ce que je sais c'est que lorsque j'utilise ma .dll comme cela

lngCmpSize& = COMPRESSE_TURBO(StrPtr(Text), StrPtr(compresse_tempon_string$), l_ori&, True)

le passage est 4 à 10 fois plus rapide(celons la taille de la string) que si j'écrit cela :

lngCmpSize& = COMPRESSE_TURBO(byval Text, byval compresse_tempon_string$, l_ori&, True)

j'en déduit donc que pour Zlib cela doit être le même problème
lngResult& = compress2(ByVal compresse_tempon_string$, lngCmpSize&, ByVal Text, l_ori&, CompressionLevel)

d'ailleur j'ai ESSAYER ! ! !, La Zlib.dll comme cela avec compresse_tempon_string$ deux fois plus gros, et bien j'ai perdu 11% de vitesse, et à 25% à 4x fois

donc byval copie

je sais j'ai toujours appris depuis longtemps dans les procédure basic que byval est plus rapide à passer les paramètre que byref, mais en extérieur avec des tailles de string pareil !
et malheureusement je ne peut pas travailler autrement qu'avec du string dans mon programmes !
c'est pour cela que je poser la question :
Est-ce qu'il y a une autre façons de compresser un string avec Zlib ou d'autres .... sans utiliser byval ! Genre un pointeur :

regarde :

voila la déclare Zlib :
Private Declare Function compress2 Lib "zlib.dll" (dest As Any, destLen As Any, src As Any, ByVal srcLen As Long, ByVal level As Long) As Long

voilà la déclare de ma .dll :
Public Declare Function COMPRESSE_TURBO Lib "COMPRESSE_TURBO" (ByVal source As Long, ByVal desti As Long, ByVal LONGUEUR As Long, ByVal si_string As Boolean) As Long

et dans .asm :
COMPRESSE_TURBO PROC EXPORT SOURCE:DWORD,DESTI:DWORD,LONGUEUR,SI_STRING:DWORD
mov esi,source
mov edi,desti
...
ETC..

donc je trail directement avec le pointeur de 4 octets récupérer par strptr() !!!
et non un BYVAL de la chaine !!!

peut-être qu'il y a d'autre compression plus rapide que Zlib pour les string !
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
234
Ben ...
Tu compares-là carottes avec navets !
StrPtr(Text) et Text sont deux choses totalement distinctes !
Ta différence de vitesse ne résulte pas de ByVal ou Byref, mais d'un traitement (alors forcément distinct) sur deux choses distinctes.

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.