Salutations à tous ceux qui lisent :) Lehub cible ne correspond pas au contenu de l'article, mais que faire ... - il n'y a pas de thèmes à cet effet, mais le plus approprié est "C", car les lecteurs pourront plus facilement percevoir ce qui est écrit.Objet de l'article
Une option pour résoudre le problème du contrôle des variables globales lors de l'écriture du programme d'installation / désinstallation à l'aide de NSIS .Petite introduction
Lors de l'écriture de code nsis, le programmeur a la possibilité d'utiliser des variables globales dont la portée est l'ensemble du projet. Il n'y en a que 20: 0 $ - 9 $ et R0 $ - R9 $.Il est très pratique de les utiliser, car cela élimine le besoin d'introduire des variables supplémentaires formellement destinées à résoudre les problèmes cibles. Je dis, officiellement, parce que toutes les variables nsis ont une portée globale et si elles diffèrent en quoi que ce soit, alors uniquement avec le qualificatif const (en termes C / C ++):!define variable1 ''value 1''
Fonctionnalités:- variable statique de portée globale;
- Initialisé lors de la déclaration;
- Méthode de contact: $ {variable1}
Var variable2
Fonctionnalités:- Variable dynamique de portée mondiale;
- Il est déclaré n'importe où par code, mais au-dessus du premier appel;
- Il est initialisé autant de fois que nécessaire, mais uniquement à l'intérieur des blocs fonctionnels et des macros;
- Méthode d'accès: $ variable2
Ainsi, compte tenu des caractéristiques ci-dessus, il devient clair que la création ciblée de variables autres que statiques est difficile à justifier, car les variables globales existent déjà par défaut, il y en a suffisamment pour satisfaire tous les besoins (et sinon, vous devez poser les questions "appropriées" au programmeur) et toutes les autres ne feront probablement qu'encombrer le code.description du problème
Mais le problème est que ce code génère toujours des erreurs:
Function F1
StrCpy $0 "vladimir"
FunctionEnd
Function F2
StrCpy $0 "alexei"
Call F1
${If} $0 == "alexei" ;
;
${EndIf}
FunctionEnd
Et vous pouvez en trouver de nombreux exemples, et les artisans de la programmation sur nsis pourraient résoudre ce problème du mieux qu'ils le pourraient:- Quelqu'un a regardé attentivement toutes les variables (ces personnes doivent ériger un monument);
- Quelqu'un, principalement les créateurs de divers plug-ins, voulant à chaque fois utiliser l'une des variables présentées, l'a fait pousser sur la pile, et après la fin de l'utilisation, ils ont renvoyé la valeur principale en appelant Pop;
- Et quelqu'un a produit des variables via Var, comme décrit ci-dessus.
En tout cas, ils ont tous été confrontés au problème de l'absence d'un mécanisme universel qui résout le problème du suivi de l'état des variables globales.Ici, je me permets de lui offrir (problèmes) une solution universelle.Solution au problème
Pour commencer, le lien vers NSISList est un plugin qui introduit la possibilité d'utiliser une structure de données de type liste, qui doit être prise de la même manière que std :: list en C ++ est perçu.La deuxième étape est le code source du mécanisme de résolution de problèmes :
!verbose 3
!include NSISList.nsh ; *
!define InitDump "!insertmacro _InitDump"
!macro _InitDump
!ifdef __UNINSTALL__
Call un.InitDump
!else
Call InitDump
!endif
!macroend
!macro Func_InitDump un
Function ${un}InitDump
# $0-$9
${List.Create} d0
${List.Create} d1
${List.Create} d2
${List.Create} d3
${List.Create} d4
${List.Create} d5
${List.Create} d6
${List.Create} d7
${List.Create} d8
${List.Create} d9
# $R0-$R10
${List.Create} dR0
${List.Create} dR1
${List.Create} dR2
${List.Create} dR3
${List.Create} dR4
${List.Create} dR5
${List.Create} dR6
${List.Create} dR7
${List.Create} dR8
${List.Create} dR9
FunctionEnd
!macroend
!insertmacro Func_InitDump ""
!insertmacro Func_InitDump "un."
!define Dump "!insertmacro _Dump"
!macro _Dump
!ifdef __UNINSTALL__
Call un.Dump
!else
Call Dump
!endif
!macroend
!macro Func_Dump un
Function ${un}Dump
# $0-$9
${List.Add} d0 $0
${List.Add} d1 $1
${List.Add} d2 $2
${List.Add} d3 $3
${List.Add} d4 $4
${List.Add} d5 $5
${List.Add} d6 $6
${List.Add} d7 $7
${List.Add} d8 $8
${List.Add} d9 $9
# R0-R9
${List.Add} dR0 $R0
${List.Add} dR1 $R1
${List.Add} dR2 $R2
${List.Add} dR3 $R3
${List.Add} dR4 $R4
${List.Add} dR5 $R5
${List.Add} dR6 $R6
${List.Add} dR7 $R7
${List.Add} dR8 $R8
${List.Add} dR9 $R9
FunctionEnd
!macroend
!insertmacro Func_Dump ""
!insertmacro Func_Dump "un."
!define Undump "!insertmacro _Undump"
!macro _Undump
!ifdef __UNINSTALL__
Call un.Undump
!else
Call Undump
!endif
!macroend
!macro Func_Undump un
Function ${un}Undump
# $0-$9
${List.Pop} $0 d0
${List.Pop} $1 d1
${List.Pop} $2 d2
${List.Pop} $3 d3
${List.Pop} $4 d4
${List.Pop} $5 d5
${List.Pop} $6 d6
${List.Pop} $7 d7
${List.Pop} $8 d8
${List.Pop} $9 d9
# R0-R9
${List.Pop} $R0 dR0
${List.Pop} $R1 dR1
${List.Pop} $R2 dR2
${List.Pop} $R3 dR3
${List.Pop} $R4 dR4
${List.Pop} $R5 dR5
${List.Pop} $R6 dR6
${List.Pop} $R7 dR7
${List.Pop} $R8 dR8
${List.Pop} $R9 dR9
FunctionEnd
!macroend
!insertmacro Func_Undump ""
!insertmacro Func_Undump "un."
Et la troisième étape est une petite description de son fonctionnement:chaque fonction créée et conçue selon la règle décrite par le commentaire de code principal précédent sera absolument protégée du point de vue du danger de réécrire les variables globales $ 0- $ 9, $ R0- $ R9 à l'intérieur, et donc - de violation de la logique de la fonction appelante.Cela fonctionne comme ceci:- La fonction F1 elle-même n'est pas appelée directement,
Call F1
et à travers le macro wrapper${F1} [paramIn1 [paramIn2]...[paramInN]] [paramOut1 [paramOut2]...[paramOutM]]
- Même avant d'appeler directement la fonction, elle sera appelée
${Dump}
en conséquence, les valeurs actuelles des variables $ 0- $ 9, $ R0- $ R9 sont enregistrées dans Dump. Sous le capot, il a beaucoup de listes, chacune liée à sa variable cible; - Chargement sur la pile de toutes les variables cibles de la fonction
Push ${paramIn1} Push ${paramIn2} ... Push ${paramInN}
(si nécessaire); - La fonction sera appelée;
- La fonction exécutera sa logique et quittera;
- L'appel aura lieu
${Undump}
en conséquence, les valeurs des variables globales stockées lors du dernier appel de $ {Dump} seront restaurées; - Déchargement des résultats de la fonction de la pile
Pop ${paramOut1} Pop ${paramOut2} ... Pop ${paramOutM}
(si nécessaire); - Le wrapper de macro sur la fonction F1 achèvera son travail.
Conclusion
En conséquence, nous avons obtenu une conception universelle pour une écriture sûre du code nsis.Vous pouvez même dire qu'il n'apporte aucun inconvénient, sauf que le code compilé fonctionnera pendant environ 30 ms. Ralentissez.J'espère que cela rend la vie plus facile à quelqu'un :)Merci!