variable locale qui change de valeur

Archive.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

variable locale qui change de valeur

Message par Dr. Dri »

dans ma fonction pour passer une image en RTF je n'ai pas l'ensemble de mes variables locales qui changent de valeur mais juste une. donc c'est pas un décalage de la pile. ce bug ne se produit que pour les bitmaps en mémoire.

Code : Tout sélectionner

Procedure.s ImageToEditor(Image.l)
  Protected Editor.s, hDC.l, bih.BitmapInfoHeader
  Protected *HeaderBits.Bytes, *ImageBits.Bytes, c.l, i.l
  Protected *Editor.Characters, *HexBuffer.Characters = @"0123456789abcdef"
  
  ;initialisation des données
  bih\biSize  = SizeOf(BitmapInfoHeader)
  *HeaderBits = bih
  
  ;récupère un dc valide
  hDC = GetDC_(#Null)
  
  ;si on récupère pas les infos du Bitmap on libère le DC
  If hDC And Not GetDIBits_(hDC, ImageID(Image), 0, 0, #Null, *HeaderBits, #DIB_RGB_COLORS)
    ReleaseDC_(#Null, hDC)
    hDC = #Null
  ;sinon on alloue la mémoire nécessaire
  Else
    *ImageBits = AllocateMemory(bih\biSizeImage)
  EndIf
  
  ;serait-ce un bug ? le bloc ci-dessous change la valeur de *ImageBits
  t = *ImageBits
  
  ;si la mémoire n'a pas été allouée on s'arrête là
  If Not *ImageBits
    ReleaseDC_(#Null, hDC)
    hDC = #Null
  ;sinon on rempli la zone de mémoire avec les données de l'image
  ElseIf Not GetDIBits_(hDC, ImageID(Image), 0, bih\biHeight, *ImageBits, *HeaderBits, #DIB_RGB_COLORS)
    ;mais en cas d'échec il faut libèrer la mémoire
    FreeMemory(*ImageBits)
    *ImageBits = #Null
  EndIf
  
  ;on rétablie la valeur d'origine
  *ImageBits = t
  
  ;si tout est oké y reste plus qu'à créer le RTF
  If *ImageBits
    ;le plus rapide c'est de directement créer la chaine et de travailler avec un pointeur
    Editor  = "{\rtf1 {\pict\dibitmap " + Space((SizeOf(BitmapInfoHeader) + bih\biSizeImage) * 2) + " }}"
    *Editor = @Editor
    
    ;pour le pointeur faut pas oublier qu'on démarre pas au début de la chaine
    c = Len("{\rtf1 {\pict\dibitmap ")
    i = 0
    While i < SizeOf(BitmapInfoHeader)
      ;un octet se représente avec deux chiffres hexa (de $00 à $FF)
      *Editor\c[c+0] = *HexBuffer\c[ HiNibble(*HeaderBits\b[i]) ]
      *Editor\c[c+1] = *HexBuffer\c[ LoNibble(*HeaderBits\b[i]) ]
      i + 1
      c + 2
    Wend
    
    i = 0
    While i < bih\biSizeImage
      *Editor\c[c+0] = *HexBuffer\c[ HiNibble(*ImageBits\b[i]) ]
      *Editor\c[c+1] = *HexBuffer\c[ LoNibble(*ImageBits\b[i]) ]
      i + 1
      c + 2
    Wend
    
    ReleaseDC_(#Null, hDC)
  EndIf
  
  ;retourne le résultat dans une chaine de caracteres
  ;heureusement que la limitation n'existe plus parce que ca grimpe vite
  ProcedureReturn Editor
EndProcedure

;charge une magnifique image créée par moi meme
If LoadImage(1, "dri.bmp") And CopyImage(1, 0)
  ;image 0 -> 100% en mémoire
  :image 1 -> DIB Section
  s.s = ImageToEditor(0)
EndIf

;crée un magnifique RTF (il est magnifique grace à l'image =)
If s And CreateFile(0, "dri.rtf")
  WriteString(0, s)
  CloseFile(0)
  
  ;chez moi sur ma vieille config avec cette petite (mais magnifique) image
  ;l'affichage du "fini" est instantanée avec le debugger
  ;vive les pointeurs pour ces performances :D
  Debug "fini"
EndIf
Fred
Site Admin
Messages : 2652
Inscription : mer. 21/janv./2004 11:03

Message par Fred »

Peut etre un petit dépassement lors de l'utilisation d'un pointeur ? T'as essayé de commenter un peu plus de code pour mieux isoler le probleme ?
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Code : Tout sélectionner

  ;serait-ce un bug ? le bloc ci-dessous change la valeur de *ImageBits
  t = *ImageBits
 
  ;si la mémoire n'a pas été allouée on s'arrête là
  If Not *ImageBits
    ReleaseDC_(#Null, hDC)
    hDC = #Null
  ;sinon on rempli la zone de mémoire avec les données de l'image
  ElseIf Not GetDIBits_(hDC, ImageID(Image), 0, bih\biHeight, *ImageBits, *HeaderBits, #DIB_RGB_COLORS)
    ;mais en cas d'échec il faut libèrer la mémoire
    FreeMemory(*ImageBits)
    *ImageBits = #Null
  EndIf
 
  ;on rétablie la valeur d'origine
  *ImageBits = t 
En fait je n'ai jamais eu de cas de figure où *ImageBits serait null, (ca voudrait dire que je n'ai pas réussi à obtenir de hDC ou à allouer et remplir le buffer de l'entete)

La seule chose qui peut se passer, pour qu'*ImageBits change de valeur, c'est que le second appel à la fonction échoue, auquel cas je met à null. Comme je ne transmet pas l'adresse du pointeur a la fonction y'a pas de raison que GetDIBits le modifie. Je ne comprend vraiment pas pourquoi la variable change de valeur. Surtout que c'est la seule à changer dans la mesure où j'utilise la rustine "t" pour rétablir la valeur d'origine.

Dri

PS. le tout testé à grand renfort de Debug
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

J'ai regardé les structures et le code asm généré par le not mais je n'ai rien vu de particulier

Tu pourrais essayer de mettre la variable *ImageBits en globale pour voir si tu as le même problème
Répondre