Salam kepada semua yang membaca :)Hub target tidak sesuai dengan konten artikel, tetapi apa yang harus dilakukan ... - tidak ada yang tematik untuk tujuan tersebut, tetapi yang paling cocok adalah "C", karena pembaca itu akan dengan mudah dapat memahami apa yang ditulis.Tujuan artikel
Opsi untuk memecahkan masalah mengendalikan variabel global saat menulis installer / uninstaller menggunakan NSIS .Pengantar kecil
Saat menulis kode nsis, programmer memiliki kesempatan untuk menggunakan variabel global yang ruang lingkupnya adalah keseluruhan proyek. Hanya ada 20 di antaranya: $ 0- $ 9 dan $ R0- $ R9.Sangat nyaman untuk menggunakannya, karena ini menghilangkan kebutuhan untuk memperkenalkan variabel tambahan yang secara formal dimaksudkan untuk memecahkan masalah target. Saya katakan, secara formal, karena setiap variabel nsis memiliki cakupan global dan jika mereka berbeda dalam hal apa pun, maka hanya dengan const kualifikasi (berbicara dalam istilah C / C ++):!define variable1 ''value 1''
Fitur:- variabel statis lingkup global;
- Diinisialisasi setelah deklarasi;
- Metode Kontak: $ {variable1}
Var variable2
Fitur:- Variabel dinamis lingkup global;
- Itu dinyatakan di mana saja dengan kode, tetapi di atas panggilan pertama;
- Ini diinisialisasi sebanyak yang diperlukan, tetapi hanya di dalam blok fungsi dan makro;
- Metode Akses: $ variabel2
Dengan demikian, dengan mempertimbangkan fitur-fitur di atas, menjadi jelas bahwa pembuatan target variabel apa pun selain statis sulit untuk dibenarkan, karena variabel global sudah ada secara default, ada cukup banyak untuk memenuhi kebutuhan apa pun (dan jika tidak, Anda perlu mengajukan pertanyaan yang "sesuai" kepada programmer) dan yang lainnya kemungkinan besar hanya akan menyumbat kode.Deskripsi masalah
Tetapi masalahnya adalah, kode ini selalu menghasilkan kesalahan:
Function F1
StrCpy $0 "vladimir"
FunctionEnd
Function F2
StrCpy $0 "alexei"
Call F1
${If} $0 == "alexei" ;
;
${EndIf}
FunctionEnd
Dan Anda dapat menemukan banyak contoh tentang hal ini, dan pengrajin pemrograman pada nsis dapat memecahkan masalah ini sebaik mungkin:- Seseorang hanya dengan cermat mengamati semua variabel (orang-orang seperti itu perlu mendirikan sebuah monumen));
- Seseorang, terutama pencipta berbagai plug-in, setiap kali ingin menggunakan variabel apa pun yang disajikan, membuatnya Push ke stack, dan setelah akhir penggunaan mereka mengembalikan nilai primer dengan menelepon Pop;
- Dan seseorang menghasilkan variabel melalui Var, seperti dijelaskan di atas.
Bagaimanapun, mereka semua menghadapi masalah kurangnya mekanisme universal yang memecahkan masalah pemantauan keadaan variabel global.Di sini saya membiarkan diri saya menawarkan (masalah) solusi universal.Solusi untuk masalah tersebut
Sebagai permulaan, tautan ke NSISList adalah plugin yang memperkenalkan kemampuan untuk menggunakan struktur data tipe-daftar, yang harus diambil dengan cara yang sama seperti yang dirasakan oleh std :: list di C ++.Langkah kedua adalah kode sumber dari mekanisme pemecahan masalah :
!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."
Dan langkah ketiga adalah deskripsi kecil tentang cara kerjanya:Setiap fungsi dibuat dan dirancang sesuai dengan aturan yang dijelaskan oleh komentar kode utama sebelumnya akan benar-benar dilindungi dari sudut pandang bahaya menimpa variabel global $ 0 - $ 9, $ R0 - $ R9 di dalam dirinya sendiri, dan oleh karena itu - dari pelanggaran logika fungsi pemanggilan.Ini berfungsi seperti ini:- Fungsi F1 itu sendiri tidak disebut secara langsung,
Call F1
dan melalui pembungkus makro${F1} [paramIn1 [paramIn2]...[paramInN]] [paramOut1 [paramOut2]...[paramOutM]]
- Bahkan sebelum fungsi dipanggil langsung, itu akan dipanggil
${Dump}
sebagai hasilnya, nilai saat ini dari variabel $ 0- $ 9, $ R0- $ R9 disimpan dalam Dump. Di bawah tenda ia memiliki banyak daftar, masing-masing terikat pada variabel targetnya; - Memuat pada stack semua variabel target untuk fungsi
Push ${paramIn1} Push ${paramIn2} ... Push ${paramInN}
(jika diperlukan); - Fungsi akan dipanggil;
- Fungsi akan menjalankan logikanya dan keluar;
- Panggilan akan terjadi
${Undump}
sebagai hasilnya, nilai-nilai variabel global yang disimpan pada panggilan terakhir $ {Dump} akan dikembalikan; - Membongkar hasil fungsi dari tumpukan
Pop ${paramOut1} Pop ${paramOut2} ... Pop ${paramOutM}
(jika diperlukan); - Pembungkus makro pada fungsi F1 akan menyelesaikan pekerjaannya.
Kesimpulan
Sebagai hasilnya, kami mendapatkan desain universal untuk penulisan kode nsis yang aman.Anda bahkan dapat mengatakan bahwa itu tidak membawa minus, kecuali bahwa kode yang dikompilasi akan bekerja sekitar 30 ms. lebih lambat.Semoga ini membuat hidup lebih mudah bagi seseorang :)Terima kasih!