bonjour.
j'ai depuis peu integre lua dans mes applis, et je le trouve vraiment utile.
j'ai voulu aller plus loin en d�couvrant IUP qui permet de d�finir dans le script lua la creation d'interfaces GUI. super me suis-je dit.
sauf que je suis toujours sous vc6 compilation en statique, multi thread, avec architecture MDI.
pour les scripts lua simples, ca passe tout seul,
mais d�s qu'on attaque iupluacontrols, avec l'appel de la fonction iup.MainLoop() pour g�rer l'interaction du composant graphique avec l'utilisateur, j'ai systematiquement un plantage au retour du script, avec une gestion des messages qui semble partir en live du cot� windows.
le seul moyen que j'ai trouv� pour �viter les plantages malheureux, c'est de mettre l'appel du script dans un thread de travail.
mais ca engendre d'autres problemes:
- passage de parametres au script, puisque l'appel est sorti de son contexte, masi ca se r�soud.
- linearit� du processus en cours bris�e. un thread de travail se d�marre, et finit dans le vide.
- renvoi des parametres de retours difficile. j'ai encore du mal avec la gestion des communications inter process.
exemple de code pour integration du script.
script lua simple provoquant le plantage..Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 lua_State * state; // on créer un contexte d'exécution de Lua state = lua_open(); // on charge les bibliothèques standards de Lua luaL_openlibs(state); // on lance le script lua, contenu dans le CString script et chargé par avance. if (luaL_dostring(state,(LPCTSTR)script)!=0) { // il y a eu une erreur dans le script CString temp; temp.Format("%s\n",lua_tostring(state,-1)); AfxMessageBox((LPCTSTR)temp,MB_OK); return -1; } // choix de la fonction à appeller dans le script lua_settop(state,0); lua_getglobal(state, "appel_fonction"); if (!lua_isfunction(state,-1)) { // la fonction n'existe pas CString temp; temp.Format("la fonction n'existe pas\n"); MessageBox(NULL,temp,"erreur",MB_OK); lua_pop(state,1); } else { // appel, 0 parametres, 1 retour if (lua_pcall(state, 0, 1, 0) != 0) { CString temp; temp.Format("error running function `f': %s",lua_tostring(state, -1)); MessageBox(NULL,temp,"erreur",MB_OK); } else { // recuperer la valeur en retour int indice=lua_gettop(state); if (indice==1) { if (lua_isstring(state,1)) { CString temp; temp.Format("valeur : %s\n",lua_tostring(state,1)); script=lua_tostring(state,1); } lua_pop(state,1); } } } lua_close(state);
donc, maintenant, est-ce qu'il existe un moyen de lancer ce script normalement, (sans passer par un appel � afxbeginthread pour isoler le lancement du script du reste de la machinerie)Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 require "iuplua" require "iupluacontrols" function do_something () for i=1,6e7 do end end gauge = iup.gauge{show_text="YES"} function idle_cb() local value = gauge.value do_something() value = value + 0.1 if value > 1.0 then value = 0.0 end gauge.value = value return iup.DEFAULT end dlg = iup.dialog{gauge; title = "IupGauge"} iup.SetIdle(idle_cb) dlg:showxy(iup.CENTER, iup.CENTER) iup.MainLoop() -- LA c'est à cause de la gestion des messages que ca doit planter.
ou dois-je continuer dans la voie des threads pour ce type de script, et alors se pose le probleme de r�cuperer les valeurs en retour pour continuer le d�roulement des actions qui ont necessit�es un scriptage dans une partie intermediaire du code.
plusieurs pistes: messages personalis�s, callback, synchro des thread ,
mais je sais pas trop lequel serait le plus efficace pour savoir que le thread est fini et a un processus � reprendre ..
coseils, id�es.??
pour etre complet, integrer IUP nescessite la presence des dll suivantes dans le path:
cd.dll
cdlua51.dll
freetype.dll
iupcd.dll
iupcontrols.dll
iuplua51.dll
iupluacontrols51.dll
lua5.1.dll
pas encore trouv� comment int�grer tout ca en lien statique avec le prog..
j'aime pas les dll que les utilisateurs peuvent effacer ou d�placer, ou remplacer..