Differenze tra le versioni di "Intercettare i dati inviati allo standard output da un programma C"

Da Gambas-it.org - Wikipedia.
Riga 10: Riga 10:
  
 
===Esempio pratico===
 
===Esempio pratico===
Facciamo, dunque, un semplice esempio.
+
Facciamo, dunque, un semplice esempio, nel quale il codice dell'applicativo Gambas include anche il codice del programma scritto in C:
 
 
Il codice del programma, scritto in C, sarà il seguente:
 
#include <stdio.h>
 
 
 
void main(int argc, char **argv) {          <FONT color=gray>/* Riceve il PID del programma Gambas */</font>
 
 
  printf("%s", argv[1]);
 
 
 
}
 
 
 
 
 
Il codice dell'applicativo Gambas sarà il seguente:
 
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
   
 
   
 
   Dim s As String
 
   Dim s As String
 +
 +
<FONT color=gray>' ''Va a creare il programma scritto in C:''</font>
 +
  Crea_C()
 
    
 
    
  <FONT color=gray>' ''Avvia il programma, scritto in C, inviadogli - come argomento - il PID del programma Gambas:''</font>
+
  <FONT color=gray>' ''Avvia il programma, scritto in C, inviandogli - come argomento - il PID del programma Gambas:''</font>
   Shell "<FONT color=gray>''/percorso/del/programma_C''</font> " & Application.Handle <FONT color=#B22222>To s</font>
+
   Shell "/tmp/programma_C " & Application.Handle <FONT color=#B22222>To s</font>
 
   
 
   
 
   Print "Il PID dell'applicativo Gambas letto dalla variabile 's' = "; <FONT color=#B22222>s</font>
 
   Print "Il PID dell'applicativo Gambas letto dalla variabile 's' = "; <FONT color=#B22222>s</font>
 +
 +
'''End'''
 +
 +
'''Private''' Procedure Crea_C()
 +
 +
  File.Save("/tmp/programma_C.c", "#include <stdio.h>\n\n" &
 +
                                  "void main(int argc, char **argv) {  <FONT color=gray>/* Riceve il PID del programma Gambas */</font>\n" &
 +
                                  "  printf(\"%s\", argv[1]);\n}")
 +
 +
  Shell "gcc -o /tmp/programma_C /tmp/programma_C.c" Wait
 
   
 
   
 
  '''End'''
 
  '''End'''
Riga 38: Riga 38:
 
=Programma C che invia dati allo ''standard output'' durante il suo funzionamento=
 
=Programma C che invia dati allo ''standard output'' durante il suo funzionamento=
 
In quest'altro caso il programma Gambas avvia il programma scritto in C, il quale invierà i dati allo ''standard output'' successivamente durante il suo funzionamento.
 
In quest'altro caso il programma Gambas avvia il programma scritto in C, il quale invierà i dati allo ''standard output'' successivamente durante il suo funzionamento.
 
  
 
==Usando la Classe ''Process''==
 
==Usando la Classe ''Process''==
Riga 44: Riga 43:
 
<BR>Lo ''standard output'' del programma C sarà, quindi, intercettato da un'apposita subroutine di Gambas, che viene sollevata quando c'è qualcosa da leggere nello ''standard output''. I dati saranno raccolti da una specifica variabile appositamente dichiarata per gestire il processo avviato del programma scritto in C.
 
<BR>Lo ''standard output'' del programma C sarà, quindi, intercettato da un'apposita subroutine di Gambas, che viene sollevata quando c'è qualcosa da leggere nello ''standard output''. I dati saranno raccolti da una specifica variabile appositamente dichiarata per gestire il processo avviato del programma scritto in C.
  
Facciamo, dunque, un semplice esempio.
+
Facciamo, dunque, un semplice esempio, nel quale il codice dell'applicativo Gambas, contenente anche il codice del programma scritto in C, sarà il seguente:
 
 
Il codice del programma, scritto in C, sarà il seguente:
 
#include <stdio.h>
 
#include <unistd.h>
 
 
 
void main() {
 
 
  int i;
 
 
 
  for (i = 1; i <= 5000; i++) {
 
 
    if ((i % 100) == 0) {
 
      printf("%d\n", i);
 
      sleep(1);
 
    }
 
 
  }
 
 
}
 
 
 
 
 
Il codice dell'applicativo Gambas sarà il seguente:
 
 
  Private <FONT color=blue>pr</font> As Process
 
  Private <FONT color=blue>pr</font> As Process
 
   
 
   
Riga 73: Riga 49:
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
   
 
   
   <FONT color=blue>pr</font> = Shell "<FONT color=gray>''/percorso/del/programma_C''</font>" <FONT color=#B22222>For Input As "processo"</font>
+
<FONT color=gray>' ''Va a creare il programma scritto in C:''</font>
 +
  Crea_C()
 +
 +
   <FONT color=blue>pr</font> = Shell "/tmp/programma_C" <FONT color=#B22222>For Input As "Processo"</font>
 
    
 
    
 
  '''End'''
 
  '''End'''
 
 
   
 
   
 
  '''Public''' Sub <FONT color=#B22222>processo_Read()</font>
 
  '''Public''' Sub <FONT color=#B22222>processo_Read()</font>
Riga 88: Riga 66:
 
    
 
    
 
  '''End'''
 
  '''End'''
 
+
 +
'''Private''' Procedure Crea_C()
 +
 +
  File.Save("/tmp/programma_C.c", "#include <stdio.h>\n" &
 +
                                  "#include <unistd.h>\n\n" &
 +
                                  "void main() {\n\n" &
 +
                                  "  int i;\n\n" &
 +
                                  "  for (i = 1; i <= 5000; i++) {\n" &
 +
                                  "    if ((i % 100) == 0) {\n" &
 +
                                  "      printf(\"%d\\n\", i);\n" &
 +
                                  "      sleep(1);\n    }\n  }\n}")
 +
 +
  Shell "gcc -o /tmp/programma_C /tmp/programma_C.c" Wait
 +
 +
'''End'''
 
====Altro esempio====
 
====Altro esempio====
 
  Private pr As Process
 
  Private pr As Process
Riga 122: Riga 114:
 
   Shell "gcc -o /tmp/prova /tmp/prova.c" Wait
 
   Shell "gcc -o /tmp/prova /tmp/prova.c" Wait
 
    
 
    
'''End'''
 
 
 
==Usando la Classe ''File''==
 
la seguente modalità è simile alla precedente, ma si porrà in osservazione con la parola-chiave "''Watch'' " il file-device "''/dev/stdout'' " aperto con la funzione "''Open'' ".
 
 
Mostriamo un esempio.
 
 
Il codice del programma, scritto in C, sarà ancora una volta il seguente:
 
#include <stdio.h>
 
#include <unistd.h>
 
 
 
void main() {
 
 
  int i;
 
 
 
  for (i = 1; i <= 5000; i++) {
 
 
    if ((i % 100) == 0) {
 
      printf("%d\n", i);
 
      sleep(1);
 
    }
 
 
  }
 
 
}
 
 
 
Il codice dell'applicativo Gambas sarà il seguente:
 
Private fl As File
 
 
 
'''Public''' Sub Main()
 
 
  Shell "<FONT color=gray>''/percorso/del/programma_C''</font>"
 
 
 
  fl = Open "/dev/stdout" For Read <FONT color=#B22222>Watch</font>
 
 
 
'''End'''
 
 
 
'''Public''' Sub File_Read()
 
 
 
  Dim s As String
 
 
<FONT color=gray>' ''Legge i dati dalla variabile di tipo "File", con la quale si gestisce il file-device "/dev/stdout":''</font>
 
  Line Input #fl, s
 
 
 
  Print "Dato intercettato: "; s
 
 
 
 
  '''End'''
 
  '''End'''
  

Versione delle 21:47, 14 dic 2021

Mostreremo due casi, nei quali un applicativo Gambas lancia mediante la funzione Shell un programma scritto in linguaggio C, e ne intercetta i dati che quest'ultimo invia allo "standard output" (stdout). [Nota 1]


Programma C che invia immediatamente dati all'output non appena avviato

In questo caso il programma Gambas avvia il programma scritto in C, il quale invia immediatamente i dati allo standard output.

Il programma scritto in Gambas in tale circostanza intercetterà i dati, trasmessi dal programma in C allo standard output, mediante la parola "To" assegnandoli ad una variabile stringa:

Shell "/percorso/del/programma_C" To variabile_stringa

Esempio pratico

Facciamo, dunque, un semplice esempio, nel quale il codice dell'applicativo Gambas include anche il codice del programma scritto in C:

Public Sub Main()

 Dim s As String

' Va a creare il programma scritto in C:
 Crea_C()
 
' Avvia il programma, scritto in C, inviandogli - come argomento - il PID del programma Gambas:
 Shell "/tmp/programma_C " & Application.Handle To s

 Print "Il PID dell'applicativo Gambas letto dalla variabile 's' = "; s

End

Private Procedure Crea_C()

 File.Save("/tmp/programma_C.c", "#include <stdio.h>\n\n" &
                                 "void main(int argc, char **argv) {   /* Riceve il PID del programma Gambas */\n" &
                                 "   printf(\"%s\", argv[1]);\n}")

 Shell "gcc -o /tmp/programma_C /tmp/programma_C.c" Wait

End


Programma C che invia dati allo standard output durante il suo funzionamento

In quest'altro caso il programma Gambas avvia il programma scritto in C, il quale invierà i dati allo standard output successivamente durante il suo funzionamento.

Usando la Classe Process

Il programma scritto in Gambas in tale circostanza intercetterà i dati, trasmessi dal programma in C allo standard output, ponendo in osservazione il processo aperto del programma C mediante le parole "For Input" (è necessaria la risorsa "Input " anziché "Read ", perché è stato posta la funzione di attesa "sleep( ) " nel codice del programma C).
Lo standard output del programma C sarà, quindi, intercettato da un'apposita subroutine di Gambas, che viene sollevata quando c'è qualcosa da leggere nello standard output. I dati saranno raccolti da una specifica variabile appositamente dichiarata per gestire il processo avviato del programma scritto in C.

Facciamo, dunque, un semplice esempio, nel quale il codice dell'applicativo Gambas, contenente anche il codice del programma scritto in C, sarà il seguente:

Private pr As Process


Public Sub Main()

' Va a creare il programma scritto in C:
 Crea_C()

 pr = Shell "/tmp/programma_C" For Input As "Processo"
 
End

Public Sub processo_Read()
 
 Dim s As String

' Legge i dati dalla variabile, con la quale si gestisce il processo:
 Line Input #pr, s
 
 Print "Dato intercettato: "; s
  
End

Private Procedure Crea_C()

 File.Save("/tmp/programma_C.c", "#include <stdio.h>\n" &
                                 "#include <unistd.h>\n\n" &
                                 "void main() {\n\n" &
                                 "   int i;\n\n" &
                                 "   for (i = 1; i <= 5000; i++) {\n" &
                                 "     if ((i % 100) == 0) {\n" &
                                 "       printf(\"%d\\n\", i);\n" &
                                 "       sleep(1);\n     }\n   }\n}")

 Shell "gcc -o /tmp/programma_C /tmp/programma_C.c" Wait

End

Altro esempio

Private pr As Process


Public Sub Form_Open()
 
 Crea()
 
 pr = Shell "/tmp/prova" For Input As "prova"
  
End


Public Sub prova_Read()
 
 TextArea1.Text &= pr.ReadLine() & gb.NewLine
 
End


Private Procedure Crea()
 
 File.Save("/tmp/prova.c", "#include <stdio.h>\n" &
 "#include <unistd.h>\n\n" &
 "int a;\n\n" &
 "void main() {\n\n" &
 "   while (1) {\n" &
 "     printf(\"%d\\n\", a);\n" &
 "     sleep(1);\n" &
 "     a++;\n}\n\n}")
 
 Shell "gcc -o /tmp/prova /tmp/prova.c" Wait
 
End


Note

[1] Quando un programma viene eseguito, il sistema operativo genera tre file chiamati rispettivamente: "standard input ", "standard output " e "standard error ".
Di norma lo "standard input " è riferito alla tastiera, mentre lo "standard output " e lo "standard error " sono riferiti allo schermo. Ogni rapporto e riferimento ai file avviene attraverso un proprio Puntatore al file, chiamato "descrittore di file ". I descrittori di questi tre file sono rappresentati con i numeri: 0, 1 e 2.
0 = "standard input ": il programma legge i dati scritti/inviati dalla periferica.
1 = "standard output ": il programma scrive/invia dati alla periferica, la quale legge i dati inviati dal programma.
2 = "standard error ": il programma scrive/invia messaggi d'errore al video.