PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WINDEV 2024 → Dépassement de capacité lors de l'affectation
Dépassement de capacité lors de l'affectation
Débuté par Patrice TERRIER, 08 avr. 2020 19:44 - 15 réponses
Posté le 08 avril 2020 - 19:44
Lorsque je lance l'audit dynamic d'un projet, l'audit me signale un dépassement de capacité lors de l'affectation dans la fonction ci-dessous
FUNCTION ZI_SetFromFileEx(LOCAL hWnd is system int, LOCAL sFileName is string, LOCAL nUseW is int, LOCAL nUseH is int)
nRet is int = API(GDImage, "ZI_SetFromFileEx", hWnd, AnsiToUnicode(sFileName), nUseW, nUseH)
RESULT nRet


L'appel de la fonction est effectué une seule fois dans le code ci-dessous :

ZI_SetFromFileEx(gP.hCtrl, sFileName, 3000, 3000)


L'audit me dit que ce code est appelé 5722 fois!!!
alors qu'il n'est appelé qu'une seule fois, et je n'arrive pas à comprendre ce qui peut provoquer un dépassement de capacité dans la fonction.

Si quelqu'un peut m'expliquer le pourquoi du comment, par avance merci !
Membre enregistré
67 messages
Posté le 09 avril 2020 - 01:31
Ca ne vous arrive jamais de dire un simple bonjour ?
Posté le 09 avril 2020 - 11:10
J'ai oublié de dire bonjour, mais je sais dire merci quand on prend la peine de me répondre :)
Membre enregistré
384 messages
Popularité : +13 (13 votes)
Posté le 09 avril 2020 - 14:31
Bonjour,

J'ai cru comprendre que vous étiez l'auteur de GDImage, donc vous avez sûrement déjà vérifié cela, mais au cas où : se pourrait-il que ZI_SetFromFileEx ait retourné un entier 64 bits, que WinDev cherche à mettre dans un entier 32 bits ? C'est en général la raison de ce genre d'erreurs.

Quant au nombre d'appels, tout dépend où vous avez inclus votre premier appel initial ?
Membre enregistré
150 messages
Popularité : +15 (15 votes)
Posté le 09 avril 2020 - 16:06
Benjamin, merci pour votre réponse.

La fonction GDImage est de type long, elle retourne donc un entier sur 4-octets (int).

En ce qui concerne l'appel il est fait une seule fois dans la procédure ci-dessous:
Procedure LoadProject(sFileName is string, rPercent is 4-bytes real)
IF Length(sFileName) THEN
xPicSize, yPicSize are int

// On libère les sprites
// ---------------------
ZI_DeleteCtrlObject(gP.hCtrl) // Delete all objects previously associated to the GDImage control
SC_PanBottom.BTN_ScriptSave..Visible = False
IF ArrayCount(ga_Sprite) THEN ArrayDeleteAll(ga_Sprite) // Clear the global Sprite array

ZI_SetFromFileEx(gP.hCtrl, sFileName, 3000, 3000)


Si je place un Trace au début de la procédure je vois bien que je n'y passe qu'une seule foi, au moment ou je charge un nouveau projet, non pas des milliers de fois comme indiqué par l'audit dynamique. J'ai le même fonctionnement anormal (pour les 2 problèmes) en version 17 et 25.

Je suis plus ennuyé par le problème de dépassement de capacité qui m'affiche un petit triangle danger au bout de la ligne de code concernée.

--
Patrice Terrier
www.zapsolution.com
Membre enregistré
505 messages
Popularité : +18 (18 votes)
Posté le 09 avril 2020 - 18:31
Bonjour à tous,

Patrice, concernant l'avertissement d'un risque de dépassement de capacité, la suggestion de Benjamin est à considérer, d'autant plus si on lit la page d'aide de la fonction API qui explique que nous n'avons pas la maîtrise du type d'entier retourné.

Pour un exécutable 64 bits, API() retourne un entier sur 8 octets.
Pour un exécutable 32 bits, API() retourne un entier sur 4 octets.

https://doc.pcsoft.fr/fr-FR/index.awp?3014005#XSYNTAXE
 : Entier sur 4 en 32 bits, entier sur 8 en 64 bits
Résultat de l'exécution de la fonction . Ce résultat peut être un code d'erreur. Le type de ce résultat dépend de la fonction exécutée. Consultez la documentation de cette fonction pour obtenir plus de détails. 
Si le résultat de la fonction est d'une taille supérieure à la taille de l'entier de la plateforme, il ne pourra pas être récupéré.


Je suppose que votre exécutable est en 64 bits.

Par ailleurs, le fait que la fonction ZI_SetFromFileEx de votre API retourne un entier sur 4 octets, devrait être sans conséquence en mode 64 bits où il est "promu" en entier sur 8 octets.
Pour revenir à un entier sur 4 octets, il faudra le "convertir" par une simple affectation vers un entier sur 4 bits pour récupérer la partie "poids faible", qui est utile.
Et si le compilateur WINDEV proteste, il est possible d'être explicite avec la fonction PoidsFaible().
https://doc.pcsoft.fr/fr-FR/?3014018&name=PoidsFaible

:-)
Membre enregistré
505 messages
Popularité : +18 (18 votes)
Posté le 09 avril 2020 - 19:05
FUNCTION ZI_SetFromFileEx(LOCAL hWnd is system int, LOCAL sFileName is string, LOCAL nUseW is int, LOCAL nUseH is int)
nRet is int = LoWord( API(GDImage, "ZI_SetFromFileEx", hWnd, AnsiToUnicode(sFileName), nUseW, nUseH), 4)
RESULT nRet
Posté le 09 avril 2020 - 19:24
Patrice TERRIER a écrit :
Lorsque je lance l'audit dynamic d'un projet, l'audit me signale un dépassement de capacité lors de l'affectation dans la fonction ci-dessous
[code:wl]
FUNCTION ZI_SetFromFileEx(LOCAL hWnd is system int, LOCAL sFileName is string, LOCAL nUseW is int, LOCAL nUseH is int)
nRet is int = API(GDImage, "ZI_SetFromFileEx", hWnd, AnsiToUnicode(sFileName), nUseW, nUseH)


Perso, je ne fais plus de déclaration de type "is int"... A la place je fais "is int on X" (1,2,4,8) comme ca je sais EXACTEMENT le type de variable déclaré et ca résoud normalement les problèmes de ce genre


L'audit me dit que ce code est appelé 5722 fois!!!


Je SOUPCONNE une confusion dans les noms : La fonction locale et celle dans l'api ont EXACTEMENT le même nom...
Donc, je commencerai par renommer la fonction locale avant de refaire un audit.
Membre enregistré
150 messages
Popularité : +15 (15 votes)
Posté le 09 avril 2020 - 20:09
Oui, le projet est en 64-bit.

Cependant, j'ai des tas de fonctions qui retourne un entier ou un booleen sans provoquer le message de dépassement de capacité, et çà n'explique pas le nombre anormal de signalements alors que la fonction est appelée une seule fois.

Note : Même en utilisant LoWord, le problème est identique, ce qui ne me surprend pas, car un entier de type "int" occupe toujours 4-octets que ce soit en 32 ou en 64-bit. C'est uniquement "system" qui utilise 4-octets en 32-bit et 8-octets en 64-bit.

Dans tous les cas merci pour votre retour, je pense que je vais me résigner et ajouter ce problème à la longue liste de ceux que j'ai déjà détecté.

--
Patrice Terrier
www.zapsolution.com
Membre enregistré
384 messages
Popularité : +13 (13 votes)
Posté le 09 avril 2020 - 22:27
Avez-vous par pur hasard essayé de récupérer le résultat sous forme de chaine ? Cela pourrait peut-être nous donner un indice de ce qui est réellement retourné, avant même que WinDev essaie de l'assigner à un entier (ce qu'il n'arrive pas à faire, visiblement).
Membre enregistré
150 messages
Popularité : +15 (15 votes)
Posté le 10 avril 2020 - 10:22
Bonjour Benjamin,

La valeur retournée est un entier signé égal à 0 (faux) ou à -1 (vrai), pour indiquer que le traitement a bien été effectué.
Il n'y a donc aucune raison que la valeur puisse créer un débordement, sauf si la pile de retour est endommagée quelque part (EIT_PILEWL).

Si on fait un trace de la valeur retournée on obtient "-1", ce qui signifie que la fonction a bien fait son travail.
FUNCTION ZI_SetFromFileEx(LOCAL hWnd is system int, LOCAL sFileName is string, LOCAL nUseW is int, LOCAL nUseH is int)
nRet is int = API(GDImage, "ZI_SetFromFileEx", hWnd, AnsiToUnicode(sFileName), nUseW, nUseH)
Trace(nRet)
RESULT nRet


Pour moi l'erreur se situe dans le fonctionnement de l'audit dynamique (EIT_PILEWL), dont voici le détail de l'erreur

Code erreur : 1026
Niveau : warning (EL_WARNING_EXECUTION)

Dump de l'erreur du module 'wd170vm64.dll' (17.0.287.3).
Identifiant des informations détaillées (.err) : 1026
Informations supplémentaires :
EIT_PILEWL :
Procédure globale ZI_SetFromFileEx (GDImage.ZI_SetFromFileEx), ligne 2
Procédure locale LoadProject (WIN_Main.PROCEDURE.LoadProject), ligne 11
Initialisation de WIN_Main (WIN_Main), ligne 12
EIT_DATEHEURE : 10/04/2020 10:15:00

--
Patrice Terrier
www.zapsolution.com
Membre enregistré
945 messages
Popularité : +53 (63 votes)
Posté le 10 avril 2020 - 13:32
Bonjour,

C'est moi ou le code semble s'auto lancer ? la fonction principal s'appelle "ZI_SetFromFileEx", l'api lance l'application "ZI_SetFromFileEx",

Donc l'api lance la procédure, qui lance l'api, qui lance la procedure, ainsi de suite.. donc ton depassement de pile devrait venir de la

Jordan
Membre enregistré
384 messages
Popularité : +13 (13 votes)
Posté le 10 avril 2020 - 15:00
Je penche en effet pour un effet similaire.

Le fait que la collection de procédure s'appelle apparemment GDImage, comme le nom de l'API, que les fonctions s'appellent pareil, ne doit pas aider WinDev.

Je viens de remarquer d'ailleurs que dans votre appel API(), "GDImage" n'est pas entre guillemets, comme le recommande la documentation de la fonction. De là à imaginer que WinDev fasse un appel sur sa propre collection de procédure plutôt qu'un appel à la DLL en question, il n'y a qu'un pas...

Dans tous les cas, avoir des noms différents aidera au moins à mieux s'y retrouver dans le deboguage. ;)
Membre enregistré
150 messages
Popularité : +15 (15 votes)
Posté le 10 avril 2020 - 15:01
Jordan

La véritable function se trouve dans la DLL GDImage, qui est appelé par la fonction WinDev de même nom.
Ce type de syntaxe est parfaitement légal lorsqu'on utilise du p-code WL, le problème ne vient pas de là.
Merci quand même pour le retour.

--
Patrice Terrier
www.zapsolution.com
Membre enregistré
170 messages
Popularité : +18 (18 votes)
Posté le 10 avril 2020 - 15:06
Patrice TERRIER a écrit :


... le problème ne vient pas de là.


Je sors cet élément de son contexte, mais parfois, nous avons des certitudes qui nous empêche d'avancer. ;)

--
--
Jean-Jacques
Membre enregistré
150 messages
Popularité : +15 (15 votes)
Posté le 10 avril 2020 - 15:44
Merci à tous ceux qui m'ont répondu.

C'est inutile de chercher une explication dans la fonction elle même, car si elle est désactivée l'erreur de dépassement se produit dans la prochaine instruction qui fait appel à une DLL externe,. Le problème de pile est donc dans l'audit dynamique lui-même.
Fort heureusement il n'y a pas d'erreur bloquante et l'application fonctionne tout à fait normalement lorsqu'on n'utilise pas le "GO minutieux du projet".

J'ai fait un"GO minutieux" pour voir si ce problème que j'avais déjà repéré en version 17 avait été corrigé en version 25, mais hélas non.

L'audit dynamique est quand même très pratique pour détecter des erreurs basiques.

--
Patrice Terrier
www.zapsolution.com