Newsgroup: it.comp.os.linux.development
Titolo: Convertire stringhe in codice

Hi all
non necessariamente legato a linux, ma é un problema che mi sono posto più
volte.
Supponiamo di avere, all'interno di un programma C/C++ una stringa del tipo
"printf (\"xyz %d\", 1)"
e di voler effettivamente ESEGUIRE il codice lì scritto.
Che metodo si può usare?
La cosa é anche più di una sega mentale, banalmente mi viene da pensare ad
un classico client-server.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
  -<! *Real* programmers use cat > a.out! No way, /real/ ones
        use zcat > a.out 'cause you can type faster that way. !>-
                -- from a Slashdot discussion

Che metodo si puň usare?
In C/C++ standard non c'č modo di farlo.

 In C/C++ standard non c'è modo di farlo.
Hai già approfondito l'argomento e non ne sei venuto a capo?
Niente polemica, é solo che la cosa mi interessa e mi sembra strano che non
si possa proprio fare, dopo aver visto il black magic che roba come la
libreria boost é in grado di implementare...


Hai giŕ approfondito l'argomento e non ne sei venuto a capo?
Il C, come il C++, ha uno standard ben definito.  Per quanto ti sembri
strano, quello che chiedi, _in modo standard_ (ovvero utilizzando le
librerie di supporto che sicuramente ogni compilatore mette a
disposizione), non si puň fare.  
Poi č probabile che esistano librerie specifiche che implementano un
parser di espressioni C-like, ma io non ne conosco e, in ogni caso,
non sono librerie standard.

 
Ciao,
che senso ha voler eseguire direttamente una stringa contenente 
direttive di un linguaggio di programmazione? Mi sembra non molto; un 
metodo estremamente brutto che mi viene in mente è di scrivere una 
funzione che prenda in input la stringa e, dopo aver creato un file 
sorgente c, chiami il compilatore su tale file ma sinceramente mi pare 
una schifezza!!
Ciao, Alberto

direttive di un linguaggio di programmazione[...]
Può avere senso, in determinati contesti.  Ci sono linguaggi (vedi
Python) che ti consentono di fare agevolmente una cosa del genere.

 Che metodo si puň usare?
Per girare del codice sorgente puoi usare un interpreter, tipo ROOT:
http://root.cern.ch/
Se invece vuoi girare del binario, allora proveri a fare un cast... Ma non
credo che sia quel che vuoi tu.
Ciao,
-- 
        Roberto Divia`              Love at first sight is one of the greatest
Dep:PH Bat:53 Mailbox:C02110      labour-saving devices the world has ever seen
Route de Meyrin 385               ---------------------------------------------
Case Postale                                Phone:  
+41-22-767-4994
CH-1211 Geneve 23 CERN                      Fax:    
+41-22-767-9585
Switzerland                                 E-Mail: 
Robert...@cern.ch

 un classico client-server.
Magari conviene un linguaggio dinamico, come Tcl, dove queste cose sono
facilissime.
-- 
David N. Welton
- 
http://www.dedasys.com/davidw/
Linux, Open Source Consulting
- 
http://www.dedasys.com/

se il linguaggio interpretato non deve essere per forza il C,
puoi dare un'occhiata a guile: e' una libreria che implementa
un interprete scheme, molto potente
ciao
giammy
--
Gianluca Moro          
http://groups.yahoo.com/group/embeddeditalia/
ISCRIVITI alla         Mailing List Italiana su LINUX EMBEDDED
giang...@yahoo.com
   Visit 
http://ilpinguino.altervista.org/

scusa, ma io, usando il C standard (o qualsiasi
altro linguaggio se e' per questo) posso sempre implementare
un interprete di C (o di qualsiasi altro linguaggio)
ciao
giammy

giang...@gmail.com
 wrote:

Be', senza offesa, non è che sia una grande scoperta.  Questo si 
sa. Temo non ci siamo capiti: è ovvio che ti puoi scrivere un 
interprete di C, ma non credo che l'OP volesse fare questo. 
Piuttosto, vorrebbe qualcosa di già pronto.
Le librerie standard non hanno nulla di pronto.

 facilissime.
Certamente. Solo che a volte non si puň scegliere :-)
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
-<! Computer programmers never die, they just raise an unhandled exception.!>-

 una schifezza!!
Questo metodo non é applicabile in generale, infatti.
Normalmente in un rapporto client/server si definisce un protocollo, che
necessita di interpretazione. Invece si può pensare ad un server che
"pilota" direttamente i client.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**


 non sono librerie standard.
Ok.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**


 Che metodo si può usare?
Niente di già pronto e standard si può usare. Usi un interprete come
già consigliato o te ne costruisci uno semplice te: in linux puoi
servirti di dlfc.h:
Ad esempio, una volta che hai tokenizzato l'input e hai qualcosa del
genere:
	char * cmd = "printf";
	char * arg1 = "xyz %d";
	int    arg2 = 1;
usi dlopen &co:
	void * h = dlopen( NULL, RTLD_LAZY );
	int(*func)(char*,...) = dlsym(h, cmd );
	func(arg1,arg2);
Ora, i problemi immediati che mi potrebbero venire in mente sono (apparte
la tokenizzazione) che devi conoscere il tipo di "func" per
dichiararlo e usarlo correttamente, e che il suo uso che varia in base al
numero degli argomenti.. A questo punto.. chissà se una cosa del genere
possa funzionare: prima prendi l'indirizzo della funzione così:
	void * func = dlsym( h, cmd );
poi fai quello che il compilatore produce normalmente: apri un blocco
di codice asm{} e dentro pushi gli argomenti che hai e poi fai una call
all'indirizzo che conosci.
Ok, mi sa che ho parlato troppo facile.. cmq la risposta è SI, si puo
fare, NO non si puo fare con un semplice "metodo" come hai chiesto tu.
Ciao Ciao
Matic

 fare, NO non si puo fare con un semplice "metodo" come hai chiesto tu.
Non ho mai pensato che la cosa si risolvesse alla svelta :-)
Certo l'idea dell'interprete é la più flessibile, ma anche la più costosa.
Supponiamo che:
*) Ho una classe X che tramite socket o altro é in grado di ricevere stringhe
in input
*) Questa classe X fa da proxy per l'accesso ad un certo insieme di metodi
relativi ad un insieme di oggetti istanziati nel programma.
*) Un client esterno può interagire con i live objects del programma
passando per il proxy X, senza bisogno di definire alcun protocollo
particolare, visto che gli basta comunicare il codice da eseguire.
Ecco, in uno scenario del genere cosa si potrebbe fare? Una mezza idea ce
l'ho, ma volevo sentire altre campane.
PS: Sì, forse si fa prima ad embeddare un interprete python :-)
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail** 
-<! Gesu' e' morto per i nostri peccati.  Non rendiamo inutile il suo
		martirio non commettendone !>-

particolare, visto che gli basta comunicare il codice da eseguire.
A mio parere, è una tecnica decisamente brutta (in realtà la definirei
pessima), e dal punto di vista di object orientation, e da quello
della sicurezza.  L'interfaccia è, invece, a mio parere
indispensabile, anche perché il client remoto del sistema non dovrebbe
conoscere i dettagli interni della classe.

 conoscere i dettagli interni della classe.
Per "interfaccia" intendi il protocollo di comunicazione, giusto?
Comunque in generale hai certamente ragione. Basta solo pensare alla
possibilità che al posto di interpretare l'HTTP apache dia la possibilità 
di accedere ai propri internals.
Ma avrebbe un suo pregio: la semplicità.
Ecco, esempio scemo: voglio aggiungere la possibilità estendere il mio text
editor. O ci faccio l'embed dell'engine di un linguaggio di scripting,
oppure posso usare delle estensioni precompilate. 
Questo sistema potrebbe riempire il gap e porsi come terza soluzione.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
  -<! Asynchronous inputs are at the root of our race problems. !>-
                 D. Winker and F. Prosser

Ma avrebbe un suo pregio: la semplicità.
Non condivido.  La semplicità, se messa in questi termini, apre tutta
una serie di strade molto pericolose e svincolate dal buon senso.  Non
voglio offenderti, ma quanto proponi non è assolutamente una soluzione
per alcun tipo di problema, sfugge del tutto alle buone pratiche di
programmazione.

 programmazione.
Nessuna offesa, ci mancherebbe. Si discute, no?
Al che ti chiedo: cosa ne pensi di software che hanno un'interfaccia al
proprio stato interno accessibile da un linguaggio di scripting?
Mi vengono in mente glimmer e dia che sono scriptabili in python.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
		-<! $>cd /pub	$>more beer !>-

proprio stato interno accessibile da un linguaggio di scripting?
Che espongono, appunto, un'interfaccia ;-)
Quindi va bene... invece, se quello che vuoi fare è ciò che io ho
intuito, so già che è una pessima idea ;-)

 Mi vengono in mente glimmer e dia che sono scriptabili in python.
Un'altro esempio eccellente è Apache che tramite i vari mod_ espone
moltissimo ai linguaggi che ci girano dentro, tanto che puoi anche
scriverci delle estensioni.
Blender pure con il Python, il Gimp con Perl. Puoi anche considerare
LUA. Io però non ho letto il tuo post iniziale che non è sul mio server,
quindi *esattamente* non ho capito cosa vuoi fare.
Comunque quello che dicevi prima, di farsi iniettare del codice
remotamente, è davvero tipico dei linguaggi interpretati (e comunque in
generale non è che ti metti ad eseguire codice proveniente dalla rete,
beh per Java si, ma va anche detto che ha builtin policy di sicurezza
sul codice che si frappongo all'esecuzione).
-- 
non vincono, non vinceranno, non hanno domani
la forza è nel puntello impugnato da oneste fortissime mani

scriverci delle estensioni.
In un caso come un web server, è normale che vi sia un punto
d'aggancio.  E' un'interfaccia prevista e necessaria.  Il problema di
Giuseppe mi sembrava fosse diverso.

 Giuseppe mi sembrava fosse diverso.
Certo. Il punto è che se progetta bene il suo software, può darsi che
tecniche sensate riescano comunque a risolvere il suo *vero* problema,
non quello "grosso".


[...]Il punto č che se progetta bene il suo software[...]
Il punto č proprio che a me non sembra lo stesse facendo ;-9

 intuito, so già che è una pessima idea ;-)
Se mi dici cosa hai intuito ti dico sì/no.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**


 sul codice che si frappongo all'esecuzione).
Non avevo pensato ad esecuzione di codice remoto, almeno per il momento.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**


 dell'interfaccia, ed eseguita.
Prova a dare un occhio a qualche sistema tipo XMLRPC, SOAP, CORBA (circa
in quest'ordine di difficoltà). Magari fa quello che vuoi tu, ma in
maniera decorosamente pulita.


 maniera decorosamente pulita.
Yes! XMLRPC e SOAP mi sono sembrati estremamente interessanti. Corba é
troppo complesso, al momento non mi va di addentrarmi.
L'unica cosa che devo ancora capire (oddio, ci ho dato solo una spolverata,
quindi l'unica non é di certo) é se il tcp/ip é l'unico mezzo di
comunicazione supportato. Perché per interazioni che coinvolgano una singola
macchina avere dei meccanismi di comunicazione più performanti potrebbe
essere interessante.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
	**ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
 -<! Woe to you, oh Earth and Sea, for the Devil sends the Beast with
      wrath, because He knows the time is short... !>- Revelations, XIII - 18