Подтвердить что ты не робот

C/С++, вы можете # включить файл в строковый литерал?

У меня есть исходный файл С++ и исходный файл Python. Я бы хотел, чтобы исходный файл С++ мог использовать содержимое исходного файла Python как большой строковый литерал. Я мог бы сделать что-то вроде этого:

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

Но это не сработает, потому что в конце каждой строки должно быть \. Я мог бы вручную копировать и вставлять содержимое кода Python и окружать каждую строку кавычками и завершающим \n, но это уродливо. Несмотря на то, что источник python будет эффективно скомпилирован в мое приложение на С++, я хотел бы сохранить его в отдельном файле, потому что он более организован и работает лучше с редакторами (emacs недостаточно умен, чтобы распознать, что C string literal - это код python и переключается в режим python, пока вы внутри него).

Пожалуйста, не предлагайте использовать PyRun_File, что я стараюсь избегать в первую очередь;)

4b9b3361

Ответ 1

Препроцессор C/С++ действует в единицах токенов, а строковый литерал - это единственный токен. Таким образом, вы не можете вмешиваться в середине строкового литерала, подобного этому.

Вы можете запрограммировать script.py на что-то вроде:

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

и #include, однако. Или вы можете использовать xxd ​ -i, чтобы сгенерировать статический массив C, готовый для включения.

Ответ 2

Это не приведет вас сюда, но вы получите чертовски близко.

Предполагая, что script.py содержит следующее:

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

Сначала оберните его следующим образом:

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

Затем, перед тем, как включить его, сделайте следующее:

#define STRINGIFY(x) #x

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

Вероятно, есть еще более строгий ответ, но я все еще ищу.

Ответ 3

Лучший способ сделать что-то вроде этого - включить файл в качестве ресурса, если ваша среда/набор инструментов имеет такую ​​возможность.

Если нет (например, встроенные системы и т.д.), вы можете использовать утилиту bin2c (что-то вроде http://stud3.tuwien.ac.at/~e0025274/bin2c/bin2c.c). Это займет двоичное представление файла и выплёт исходный файл C, содержащий массив байтов, инициализированных этими данными. Возможно, вам понадобится сделать некоторые настройки инструмента или выходного файла, если вы хотите, чтобы массив был "\ 0" завершен.

Включите запуск утилиты bin2c в ваш make файл (или как шаг предварительной сборки того, что вы используете для управления вашими сборками). Затем просто скомпилируйте файл и привяжите его к вашему приложению, и у вас есть ваша строка (или любое другое изображение файла), сидящее в блоке памяти, представленном массивом.

Если вы включаете текстовый файл в виде строки, вам следует знать, что окончание строк может не соответствовать ожидаемым функциям - это может быть еще одна вещь, которую вы хотите добавить в утилиту bin2c, или вы "Я хочу, чтобы ваш код обрабатывал любые строки в файле правильно. Возможно, модифицируйте утилиту bin2c, чтобы иметь переключатель" -s", который указывает, что вы хотите, чтобы текстовый файл был представлен как строка, так что окончания строки будут нормализованы, а нулевой байт будет в конце массива.

Ответ 4

Вам нужно будет выполнить некоторую собственную обработку кода Python, чтобы иметь дело с любыми двойными кавычками, обратными косыми чертами, триграфами и, возможно, другими вещами, которые появляются в нем. Вы можете в то же время превращать новые строки в \n (или обратную косую черту - избегать их) и добавлять двойные кавычки с обоих концов. Результатом будет файл заголовка, сгенерированный из исходного файла Python, который затем можно включить #include. Используйте свой процесс сборки для автоматизации этого, так что вы все равно можете редактировать источник Python как Python.

Ответ 5

Вы можете использовать Cog как часть процесса сборки (чтобы выполнить предварительную обработку и вставить код). Я признаю, что результат этого, вероятно, не идеален, так как вы в конечном итоге видите код в обоих местах. Но в любое время я вижу "Python", "С++" и "Preprocessor" в близости к closs, я считаю, что это заслуживает упоминания.

Ответ 6

Вот как автоматизировать преобразование с cmd.exe

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

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

Он назывался как

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

и прикреплен к коду

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

Это довольно зависящий от системы подход, но, как и большинство людей, я не любил шестнадцатеричный дамп.

Ответ 7

Используйте fopen, getline и fclose.