Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1384 connectés 

 


Dernière réponse
Sujet : [Borland C++ builder] Redirection sdtout
Bruce un cht'i up car bon... je suis tj bloqué...

Votre réponse
Nom d'utilisateur    Pour poster, vous devez être inscrit sur ce forum .... si ce n'est pas le cas, cliquez ici !
Le ton de votre message                        
                       
Votre réponse


[b][i][u][strike][spoiler][fixed][cpp][url][email][img][*]   
 
   [quote]
 

Options

 
Vous avez perdu votre mot de passe ?


Vue Rapide de la discussion
Bruce un cht'i up car bon... je suis tj bloqué...
JWhy oui... je vois pas pourquoi vous lui parlez de threads ...
 
comme je te disais, le probleme vient de ReadFile qui est bloquant tant que rien n'est ecrit dans ton stdout... c'est a dire que si tu as un prog qui va ecrire un truc, attendre 5 secondes, ecrire un autre truc, readfile va bloquer ton appli pendant les 5 secondes ou le prog. n'ecrit rien dans le stdout...
 
 
il faut que tu remplaces le ReadFile bloquant:

Citation :


  if(ReadFile(hReadPipe, &dest, sizeof(dest), &BytesRead, NULL)) {
   [...]
  }


 
par un test pour savoir si il y a qqchose a lire et ensuite, si il y a qqchose, le lire (qui ne sera pas bloquant puisque tu vas lire exactement ce qu'il y a):

Citation :


  PeekNamedPipe (hOutPipeRead, nil, 0, @dwRead, @dwLeft, nil);  
 
  // has anything been read?  
  if (dwLeft <> 0) then  
  begin  
    ReadFile(hOutPipeRead, Buffer, dwLeft, dwRead, nil);  
    [...]
  end;

Bruce Honettement je suis un peu paumé, je vois pas trop ou vous voulez en venir (il faut dire que jes thread et moi... :)).
robripper Tu crées juste un thread, tu lui passes ta fonction en param (cell qui va faire tout le travail)... etc
 
En plus ici t'es pas obligé de section critique donc ...
 
DWORD WINAPI ma_fonction(LPVOID)
{
 
       // ... rippage, normalisation, etc etc ...  :sol:  
 
      return 0;
}
antp

robripper a écrit a écrit :

Franchement moi j'utiliserais l'API c'est bien plus simple, je viens de jetter un oeil dans c++ builder  :D  
Attention, bientôt il va te faire utiliser Delphi, je connais bien antp  :hap:  :hap:




 
ok pour l'API
avec Delphi le .exe serait moins gros :P

robripper Franchement moi j'utiliserais l'API c'est bien plus simple, je viens de jetter un oeil dans c++ builder  :D  
Attention, bientôt il va te faire utiliser Delphi, je connais bien antp  :hap:  :hap:
antp

bruce a écrit a écrit :

Hu ?  :??:




 
prend l'aide de Builder à "TThread" je crois que c'est ce qu'il y aura de plus facile pour commencer...
sinon dans les exemples fournis il doit bien y en avoir un qui fait ça...

robripper Tu peux aussi modifier les priorités ...
 
SetThreadPriority(threadhandle,THREAD_PRIORITY_NORMAL);
Bruce Hu ?  :??:
antp

robripper a écrit a écrit :

 
 
DWORD threadid;
HANDLE threadhandle;
 
...
threadhandle = CreateThread(NULL,1024,ma_fonction,NULL,CREATE_SUSPENDED,&threadid);
...
TerminateThread(threadhandle,0);
 




 
y a aussi la classe TThread.
Moi j'utiliserais celle-ci, ça a l'air plus simple :)

 

[edit]--Message édité par antp--[/edit]

robripper

bruce a écrit a écrit :

Hummm... disons que je m'y connais mal ;)




 
DWORD threadid;
HANDLE threadhandle;
 
...
threadhandle = CreateThread(NULL,1024,ma_fonction,NULL,CREATE_SUSPENDED,&threadid);
...
TerminateThread(threadhandle,0);
 
==================
 
 
DWORD WINAPI ma_fonction(LPVOID)
{
       EnterCriticalSection(&crit);
 
       // ... travail ...
 
       LeaveCriticalSection(&crit);
      return 0;
}

Bruce Hummm... disons que je m'y connais mal ;)
antp pourquoi en win32 ? y a des objets pour faire des threads dans C++builder, c'est plus simple à utiliser je crois.
Bruce Heu... en Win32 j'ai du mal, un exemple de code ???
robripper

antp a écrit a écrit :

ha ouais c'est au WaitForSingleObject(pi.hProcess, 90000); qu'il bloque... j'avais pas vu.
le plus simple serait alors de le mettre dans un thread séparé je crois.




 
un thread séparé, c le truc à faire en effet...

antp ou alors:
while(!WaitForSingleObject(pi.hProcess, 1000))
{
  Application->ProcessMessages();
}
 
toutes les secondes il fait le processmessages.
je sais pas si c'est très bien comme solution.
et si le programme exécuté est calé il attend indéfiniment.
antp ha ouais c'est au WaitForSingleObject(pi.hProcess, 90000); qu'il bloque... j'avais pas vu.
le plus simple serait alors de le mettre dans un thread séparé je crois.
JWhy m'etonnerait que ca marche... c'est l'appel de l'API qui est bloquant... le ProcessMessage ne resoudra rien, je pense ...
 
sinon, regarde l'aide de l'API PeekNamedPipe, la declaration en C + le code Delphi devrait pouvoir t'aider a faire la conversion .
antp si tu le met juste après le ->add il risque de pas le faire souvent pour les longues opérations
si tu le met dans la boucle en dehors du if c'est dangereux pcq ton appli risque de prendre trop de CPU pour rafraichir... il faut tester
Bruce Pas con, je vais essayer.
antp pour éviter que ça bloque il faut faire régulièrement des Application->ProcessMessages(); c'est-à dire juste après le memo->lines->add.
Peut-être que ça résoudra l'autre problème en même temps...

 

[edit]--Message édité par antp--[/edit]

Bruce Heu... bon, je doit avouer avoir du mal à piger ta syntaxe... Le pascal est qd même légèrement différent... :)
JWhy

Code :
  1. procedure TProcess.ReadScreen;
  2. var
  3.   Buffer: array[0..255] of Char;
  4.   dwLeft, dwRead : DWORD;
  5. begin
  6. //  FillChar(Buffer, SizeOf(Buffer), 0);
  7.   dwLeft := 0;
  8.   dwRead := 0;
  9.   FLastLines := '';
  10.   PeekNamedPipe (hOutPipeRead, nil, 0, @dwRead, @dwLeft, nil);
  11.   // has anything been read?
  12.   if (dwLeft <> 0) then
  13.   begin
  14.     ReadFile(hOutPipeRead, Buffer, dwLeft, dwRead, nil);
  15.     // finish buffer to PChar
  16.     Buffer[dwRead] := #0;
  17.     // combine the buffer with the rest of the last run
  18.     FLastLines := Buffer;
  19.     FLines := FLines + Buffer ;
  20.   end;
  21. end;

JWhy beuh... j'fais du Delphi, moi...  mais je vais essayer de te trouver un bout de code relativement clair...
Bruce Heu... tu n'aurrai pas un exemple de code qq part car je suis pas encore bien pro en prog... J'ai pompé ça sur un exemple fourni avec BC++ en adaptant à mes besoins...
 
Merci encore ! :)
JWhy oui, c'est normal... je me suis fait avoir de la meme facon...

Citation :


ReadFile returns when one of the following is true: a write operation completes on the write end of the pipe, the number of bytes requested has been read, or an error occurs.


c'est a dire que tant que tu n'ecris rien, ca ne "revient" pas et donc ton prog. est bloqué..
l'astuce (merci minicooler :jap: ) est d'utiliser l'API PeekNamedPipe pour savoir si il y a qqchose d'ecrit et si c'est le cas, utiliser ReadFile pour recuperer le contenu !

Bruce J'ai trouvé comment rediriger stdout
quasiment comme je le voulais (Je suis sous
Borland c++ 4.0)
Voilà, cela marche mais j'aimerais que cela marche légèrement différement...
En effet, lorsque je lance ma commande, je suis obligé d'attendre que cette
commande soit terminée pour que le résultat s'affiche dans mon Memo... De
plus, tous le temps de la commande, l'application est comme "bloquée",
impossible de déplacer la fenêtre par exemple...
Si qq un peu m'aider, cela serait vraiment sympa... Merci d'avance !
Voici mon code :
(précision, Rippack_RipFormBeta->Memo1 est le mémo dans lequel je sort,
filepos est ma ligne de commande)
 

Code :
  1. Rippack_RipFormBeta->Memo1->Clear();
  2. int FBreak;
  3. HANDLE hReadPipe;
  4. HANDLE hWritePipe;
  5. STARTUPINFO si;
  6. LPSECURITY_ATTRIBUTES lpsa = NULL;
  7. if(CreatePipe(&hReadPipe,&hWritePipe,lpsa,0))
  8. {
  9.   memset(&si, 0, sizeof(STARTUPINFO));
  10.   si.cb = sizeof(STARTUPINFO);
  11.   si.dwFlags = STARTF_USESHOWWINDOW |STARTF_USESTDHANDLES;
  12.   si.wShowWindow = SW_HIDE;
  13.   si.hStdOutput = hWritePipe;
  14.   si.hStdError = hWritePipe;
  15.   PROCESS_INFORMATION pi;
  16.   if(hWritePipe)
  17.   {
  18.     Rippack_RipFormBeta->Memo1->Lines->Add("Working..." );
  19.     Application->ProcessMessages();
  20.     if(CreateProcess(NULL,filepos.c_str(),NULL,NULL,TRUE,0,0,0,&si,&pi))
  21.     {
  22.       CloseHandle(pi.hThread);
  23.       WaitForSingleObject(pi.hProcess, 90000);
  24.       if(hReadPipe)
  25.       {
  26.         DWORD BytesRead; //unsigned long
  27.         char dest[4000];
  28.         bool RdLoopDone = false;
  29.         Rippack_RipFormBeta->Memo1->Clear();
  30.         FBreak = 1;
  31.         if(ExitCode) Screen->Cursor = crDefault;
  32.         while(!RdLoopDone)
  33.         {
  34.           memset(dest, 0, 4000);
  35.           if(ReadFile(hReadPipe, &dest, sizeof(dest), &BytesRead,
  36. NULL))
  37.           {
  38.             Rippack_RipFormBeta->Memo1->Lines->Add(String(dest));
  39.             if(BytesRead < 4000) RdLoopDone = true;
  40.             if(FBreak > 150) RdLoopDone = true;
  41.             FBreak++;
  42.             CloseHandle(hReadPipe);
  43.             CloseHandle(hWritePipe);
  44.             CloseHandle(pi.hProcess);
  45.           }
  46.         }
  47.       }
  48.     }
  49.   }
  50. }
 

[edit]--Message édité par bruce--[/edit]


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR