Вопрос

У меня есть программа на C ++, которая использует 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 для выполнения другой работы и покончить с этим.

Вот пример, который мы использовали для кроссплатформенного встраивания файлов.Это довольно упрощенно, но, вероятно, сработает для вас.

Возможно, вам также потребуется изменить способ обработки перевода строк в функции 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, в котором определен только один массив символов, содержащий содержимое файла ресурсов в шестнадцатеричном формате (чтобы избежать проблем с вредоносными символами).Этот автоматически сгенерированный исходный файл затем просто компилируется и привязывается к проекту.

Должно быть довольно легко реализовать преобразователь для дампа файла C для каждого файла ресурсов, а также написать некоторые фасадные функции для доступа к ресурсам.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top