2009-08-07 13 views
33

Ho un file sorgente C++ e un file sorgente Python. Mi piacerebbe che il file sorgente C++ fosse in grado di usare il contenuto del file sorgente Python come un grande letterale di stringa. Avrei potuto fare qualcosa di simile:C/C++, puoi # includere un file in una stringa letterale?

char* python_code = " 
#include "script.py" 
" 

Ma questo non funzionerà perché ci devono essere \ s 'alla fine di ogni riga. Potrei copiare e incollare manualmente il contenuto del codice Python e circondare ogni riga con virgolette e un \ n terminante, ma è brutto. Anche se la sorgente Python verrà effettivamente compilata nella mia app C++, mi piacerebbe tenerla in un file separato perché è più organizzata e funziona meglio con gli editor (emacs non è abbastanza intelligente da riconoscere che un C string letteral è il codice Python e passa alla modalità python mentre ci sei dentro).

Si prega di non suggerire che uso PyRun_File, che è quello che sto cercando di evitare in primo luogo;)

+0

So che questo è un duplicato. –

+3

Se si tratta di un duplicato, puoi fornire un link? Mi sono guardato intorno e non ho visto nulla con i miei termini di ricerca. –

+0

Inoltre, la versione precedente era specifica per python? Perché è una domanda più generale. –

risposta

35

Il C/C++ atti preprocessore in unità di gettoni, e una stringa letterale è una singolo token. In quanto tale, non è possibile intervenire nel mezzo di una stringa letterale come quella.

Potreste preprocess script.py in qualcosa di simile:

"some code\n" 
"some more code that will be appended\n" 

e #include che, comunque. Oppure puoi usare xxd​ -i per generare un array statico C pronto per l'inclusione.

+11

+1 per xxd. Probabilmente lo script non ha davvero bisogno di essere una stringa letterale. –

+0

Come si fa a pre-scrivere script.py in questo modo? Non vedo un modo per farlo con il CPP. A meno che tu non intenda con uno strumento esterno come sed in quell'occasione. –

+0

Uno strumento esterno, sì. Non puoi fare quello che vuoi con solo CPP. – bdonlan

1

Dovrai eseguire un po 'di elaborazione sul codice Python, per gestire doppie virgolette, barre rovesciate, trigreph e probabilmente altre cose che appaiono in esso. Puoi allo stesso tempo attivare le newline in \ n (o backslash-escape) e aggiungere le virgolette alle due estremità. Il risultato sarà un file di intestazione generato dal file di origine Python, che puoi quindi includere #include. Usa il tuo processo di compilazione per automatizzarlo, così puoi ancora modificare il sorgente Python come Python.

1

È possibile utilizzare Cog come parte del processo di compilazione (per eseguire la pre-elaborazione e incorporare il codice). Ammetto che il risultato di questo non è probabilmente l'ideale, da allora finisci per vedere il codice in entrambi i posti. Ma ogni volta che vedo "Python", "C++" e "Preprocessor" in prossimità del closs, sento che merita una menzione.

-8

Utilizzare fopen, getline e fclose.

+2

Equivalente a PyRun_File. L'idea è di aggregarla all'eseguibile al momento della compilazione, quindi non devo fare quel genere di cose. –

+1

In questo modo otterrete il contenuto del runtime del file che si trova sulla macchina in esecuzione, non il contenuto in fase di compilazione del file sulla macchina di compilazione. –

4

Il modo migliore per fare qualcosa di simile è includere il file come risorsa se il proprio ambiente/set di strumenti ha questa capacità.

In caso contrario (come i sistemi incorporati, ecc.), È possibile utilizzare un'utilità bin2c (qualcosa come http://stud3.tuwien.ac.at/~e0025274/bin2c/bin2c.c). Prenderà la rappresentazione binaria di un file e sputerà un file sorgente C che include una matrice di byte inizializzata su quei dati. Potrebbe essere necessario apportare qualche ritocco dello strumento o del file di output se si desidera che l'array sia terminato con \ 0.

Incorporare l'esecuzione dell'utilità bin2c nel makefile (o come passo di pre-generazione di qualsiasi cosa si stia utilizzando per gestire le build). Quindi basta compilare il file e collegarlo alla tua applicazione e avere la tua stringa (o qualsiasi altra immagine del file) seduta in un blocco di memoria rappresentato dall'array.

Se si include un file di testo come stringa, una cosa di cui si dovrebbe essere a conoscenza è che le terminazioni di riga potrebbero non corrispondere a ciò che le funzioni si aspettano - questa potrebbe essere un'altra cosa che si desidera aggiungere all'utilità bin2c o ti consigliamo di assicurarti che il codice gestisca le terminazioni di linea nel file in modo corretto. Forse modificare l'utilità bin2c per avere un interruttore "-s" che indica che si desidera che un file di testo sia incorporato come stringa, in modo che le terminazioni di riga vengano normalizzate e che alla fine dell'array si trovi un byte zero.

9

Questo non ti farà arrivare fino in fondo, ma ti porterà molto vicino.

Supponendo script.py contiene questo:

print "The current CPU time in seconds is: ", time.clock() 

In primo luogo, avvolgetelo in questo modo:

STRINGIFY(print "The current CPU time in seconds is: ", time.clock()) 

Poi, poco prima di includerlo, fare questo:

#define STRINGIFY(x) #x 

const char * script_py = 
#include "script.py" 
; 

C'è probabilmente una risposta ancora più stretta di quella, ma sto ancora cercando.

+0

voi signore, avete un biscotto! 2 anni di ballo intorno al numero –

+1

Ho avuto un caso (sicuramente raro) in cui talvolta avevo bisogno di includere lo stesso file del codice, e talvolta come una stringa (non chiedere;)). Così ho aggiunto nel file incluso '#ifndef STRINGIFY \ n #define STRINGIFY (x) x \ n # endif' e quando voglio includerlo come codice, mi assicuro che STRINGIFY non sia definito. Miracolosamente funziona anche con file multi-linea! –

-2

Ecco come automatizzare la conversione con cmd.exe

------ ------ html2h.bat

@echo off 
echo const char * html_page = "\ 
sed "/.*/ s/$/ \\n\\/" ../src/page.html | sed s/\"/\\\x22/g 
echo. 
echo "; 

E 'stato chiamato come

cmd /c "..\Debug\html2h.bat" > "..\debug\src\html.h" 

e allegato al codice

#include "../Debug/src/html.h" 
printf("%s\n", html_page); 

Questo è un approccio abbastanza dipendente dal sistema ma, come la maggior parte delle persone, non mi piaceva l'hex dump.

Problemi correlati