Kevin Kofler Le 11/10/2002 à 21:57Edité par Kevin Kofler le 11/10/2002 à 21:57 La variable utilisée dans ton programme BASIC est-elle bien globale?
Zeph Le 11/10/2002 à 22:37 Dans ce cas oui, mais vat_open est aussi capable d'ouvrir les variables locales.

All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez
par ici :)
Vérifie alors que, dans vat_open, tu regardes bien à la fois dans la liste des variables locales et dans celle des variables globales.
C'est du code illisible ! Je pense que ça peut être une source d'erreurs...
Peut-être qu'en traversant la VAT complète, tu auras moins de problèmes (je ne sais pas, c'est juste une suggestion).
La plupart du temps une ligne immense coupées en petits morceaux d'augmente pas la taille du résultat, ça ne peut être que bénéfique de rendre du code lisible.
Kevin Kofler Le 12/10/2002 à 17:08Edité par Kevin Kofler le 12/10/2002 à 17:08 Je trouve que la ligne
return (sym_variable = DerefSym(FindSymInFolder(vat_name(nom_variable),TempFolderName(numero_dossier_local)))) ?
sym_variable : SymFindPtr(vat_name(nom_variable),0);
est très claire.
Essaye de faire le test de validité autour de FindSymInFolder plutôt qu'autour de DerefSym:
HSYM hsym_variable;
return (({hsym_variable = FindSymInFolder(vat_name(nom_variable),TempFolderName(numero_dossier_local))));
*(unsigned long *)&hsym_variable;}) ? DerefSym(hsym_variable) : SymFindPtr(vat_name(nom_variable),0);
Ce n'est pas complètement optimisé:
SYM_ENTRY *vat_open(const char *nom_variable)
{
return (DerefSym(FindSymInFolder(vat_name(nom_variable),TempFolderName(numero_dossier_local)))) ?: SymFindPtr(vat_name(nom_variable),0);
}
Mais SYMSTR fait la même chose que vat_name, donc je l'utiliserai:
SYM_ENTRY *vat_open(const char *nom_variable)
{
return (DerefSym(FindSymInFolder(SYMSTR(nom_variable),TempFolderName(numero_dossier_local)))) ?: SymFindPtr(SYMSTR(nom_variable),0);
}
?: est une extension de GCC, au fait, x?:y est la même que x?x:y.
Oui, avec la différence que le x est évalué une seule fois. (C'est bien ce qui convient ici, mais j'ai quand-même préféré le préciser.)
Zeph Le 12/10/2002 à 18:22 J'ai déjà eu des problèmes avec x?:y, donc je préfere la méthode "classique"...
Quand à SYMSTR c'est volontairement que je ne l'utilise pas. Le fait d'appeller ma fonction à chaque fois que j'ai besoin de convertir un nom me fait gagner environ 100 octets...

All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez
par ici :)
Zeph Le 14/10/2002 à 16:11 J'aurais besoin d'une explication :
// Optention d'un pointeur ESI vers la liste, à partir de son nom (le passage de l'ESI en pointeur est normal)
char arg_strn(ESI *argument_esi)
{
ESI esi_liste=NULL;
char *pointeur_chaine=NULL;
pointeur_chaine=(char*)GetStrnArg(*argument_esi);
esi_liste=HToESI(vat_open(pointeur_chaine)->handle;
arg_list(&esi_liste);
}
Or la doc dit à propos de HToESI :
Note: If the handle is not locked, HToESI must be called again after a heap compression since the block of memory associated with the handle may have moved.
> Qu'est-ce que ça signifie, et est-ce que ça pourrait être la cause de l'erreur ?

All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez
par ici :)
Ah oui, ça pourrait être l'origine du problème.
Essaye de mettre:
HANDLE h_global; int booleen_global;
en variables globales et:
h_global=vat_open(pointeur_chaine)->handle
booleen_global=HeapGetLock(h_global);
HeapLock(h_global);
esi_liste=HToESI(h_global);
au début et:
if (!booleen_global) HeapUnlock(h_global);
quand tu as fini de lire la liste.
n>0?white_checker:black_checker
ça veut dire que si n est supérieur à 0 on retourne white checker, sinon black_checker.
D'une façon générale :
condition?instruction_si_vraie:instruction_si_fausse
Zeph Le 15/10/2002 à 18:21 Kevin > Hum ça va allourdir bcp le code parceque "esi_liste" est en fait un tableau de pointeurs ESI, donc va falloir que je crée aussi des tableaux de handle et de short...
HeapUnlock plante si le handle n'est pas locké avant d'appeller la fonction ?

All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez
par ici :)
Le problème, c'est qu'il ne faut pas appeler HeapUnlock si le bloc était déjà locké au moment de l'appel à HeapLock, d'où l'utilisation de mon booléen.
Kevin Kofler Le 15/10/2002 à 19:29Edité par Kevin Kofler le 15/10/2002 à 19:31 Je viens de voir que tu peux te passer du booléen en utilisant l'astuce suivante (inspirée de ce que fait ttstart):
HANDLE h_global;
...
HANDLE h_local;
h_local=vat_open(pointeur_chaine)->handle;
if (HeapGetLock(h_local)) h_global=0; else h_global=h_local;
HeapLock(h_local);
esi_liste=HToESI(h_local);
...
if (h_global) HeapUnlock(h_global);
Non. HeapGetLock renvoie une valeur non-nulle si le bloc est verrouillé (locké).
Donc:
if (HeapGetLock(h_local)) h_global=0; else h_global=h_local;
Si le bloc était déjà verrouillé, on met h_global à 0 pour qu'il ne sera pas déverrouillé à la fin (mais restera locké). Si le bloc n'était pas verrouillé, on stocke h_local en h_global pour pouvoir le déverrouiller à la fin.
Dans les 2 cas, on retrouve l'état d'origine du bloc.