Ответ 1
Вы можете использовать objcopy для привязки содержимого файла к символу, который может использовать ваша программа. См., Например, здесь для получения дополнительной информации.
У меня есть программа на С++, которая использует SQLite. Я хочу хранить SQL-запросы в отдельном файле - текстовом файле, а не файле исходного кода, но вставлять этот файл в исполняемый файл, как ресурс.
(Это должно выполняться в Linux, поэтому я не могу хранить его как фактический ресурс, насколько я знаю, хотя это было бы прекрасно, если бы оно было для Windows.)
Есть ли какой-нибудь простой способ сделать это, или это потребует от меня написать мою собственную систему ресурсов для Linux? (Легко, но это займет намного больше времени.)
Вы можете использовать objcopy для привязки содержимого файла к символу, который может использовать ваша программа. См., Например, здесь для получения дополнительной информации.
Использовать макросы. Технически этот файл будет исходным кодом, но он не будет выглядеть так. Пример:
//queries.incl - SQL queries
Q(SELECT * FROM Users)
Q(INSERT [a] INTO Accounts)
//source.cpp
#define Q(query) #query,
char * queries[] = {
#include "queries.incl"
};
#undef Q
Позже вы можете делать всевозможные другие обработки в этом файле одним и тем же файлом, скажем, что вы хотите иметь массив и хэш-карту из них, вы можете переопределить Q, чтобы выполнить другую работу и сделать с ней.
Вы всегда можете написать небольшую программу или script, чтобы преобразовать текстовый файл в файл заголовка и запустить его как часть процесса сборки.
Вот пример, который мы использовали для кросс-платформенного встраивания файлов. Это довольно упрощенно, но, вероятно, сработает для вас.
Вам также может потребоваться изменить способ обработки строк в функции escapeLine.
#include <string>
#include <iostream>
#include <fstream>
#include <cstdio>
using namespace std;
std::string escapeLine( std::string orig )
{
string retme;
for (unsigned int i=0; i<orig.size(); i++)
{
switch (orig[i])
{
case '\\':
retme += "\\\\";
break;
case '"':
retme += "\\\"";
break;
case '\n': // Strip out the final linefeed.
break;
default:
retme += orig[i];
}
}
retme += "\\n"; // Add an escaped linefeed to the escaped string.
return retme;
}
int main( int argc, char ** argv )
{
string filenamein, filenameout;
if ( argc > 1 )
filenamein = argv[ 1 ];
else
{
// Not enough arguments
fprintf( stderr, "Usage: %s <file to convert.mel> [ <output file name.mel> ]\n", argv[0] );
exit( -1 );
}
if ( argc > 2 )
filenameout = argv[ 2 ];
else
{
string new_ending = "_mel.h";
filenameout = filenamein;
std::string::size_type pos;
pos = filenameout.find( ".mel" );
if (pos == std::string::npos)
filenameout += new_ending;
else
filenameout.replace( pos, new_ending.size(), new_ending );
}
printf( "Converting \"%s\" to \"%s\"\n", filenamein.c_str(), filenameout.c_str() );
ifstream filein( filenamein.c_str(), ios::in );
ofstream fileout( filenameout.c_str(), ios::out );
if (!filein.good())
{
fprintf( stderr, "Unable to open input file %s\n", filenamein.c_str() );
exit( -2 );
}
if (!fileout.good())
{
fprintf( stderr, "Unable to open output file %s\n", filenameout.c_str() );
exit( -3 );
}
// Write the file.
fileout << "tempstr = ";
while( filein.good() )
{
string buff;
if ( getline( filein, buff ) )
{
fileout << "\"" << escapeLine( buff ) << "\"" << endl;
}
}
fileout << ";" << endl;
filein.close();
fileout.close();
return 0;
}
Это немного уродливо, но вы всегда можете использовать что-то вроде:
const char *query_foo = #include "query_foo.txt" const char *query_bar = #include "query_bar.txt"
Где query_foo.txt будет содержать цитируемый текст запроса.
Я видел, как это делается путем преобразования файла ресурсов в исходный файл C только с одним массивом char, содержащим содержимое файла ресурсов в шестнадцатеричном формате (во избежание проблем со вредоносными символами). Этот автоматически созданный исходный файл затем просто компилируется и привязывается к проекту.
Довольно легко реализовать преобразователь для вывода файла C для каждого файла ресурсов также для написания некоторых функций фасада для доступа к ресурсам.