Pergunta

Eu tenho um programa C++ que usa SQLite.Quero armazenar as consultas SQL em um arquivo separado - um arquivo de texto simples, não um arquivo de código-fonte - mas incorpore esse arquivo no arquivo executável como um recurso.

(Isso precisa ser executado no Linux, então não posso armazená-lo como um recurso real, até onde eu sei, embora isso fosse perfeito se fosse para o Windows.)

Existe alguma maneira simples de fazer isso ou será necessário que eu escreva meu próprio sistema de recursos para Linux?(Facilmente possível, mas demoraria muito mais tempo.)

Foi útil?

Solução

Você pode usar objcopy para vincular o conteúdo do arquivo a um símbolo que seu programa pode usar.Veja, por exemplo, aqui Para maiores informações.

Outras dicas

Você sempre pode escrever um pequeno programa ou script para converter seu arquivo de texto em um arquivo de cabeçalho e executá-lo como parte do processo de construção.

Utilize macros.Tecnicamente, esse arquivo seria Código fonte arquivo, mas não seria assim.Exemplo:

//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

Mais tarde, você poderia fazer todos os tipos de processamento nesse arquivo pelo mesmo arquivo, digamos que você gostaria de ter um array e um mapa hash deles, você poderia redefinir Q para fazer outro trabalho e terminar com ele.

Aqui está um exemplo que usamos para incorporação de arquivos em várias plataformas.É bastante simplista, mas provavelmente funcionará para você.

Você também pode precisar alterar a forma como ele lida com os feeds de linha na função 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;
}

É um pouco feio, mas você sempre pode usar algo como:

const char *query_foo =
#include "query_foo.txt"

const char *query_bar =
#include "query_bar.txt"

Onde query_foo.txt conteria o texto de consulta citado.

Eu vi isso ser feito convertendo o arquivo de recursos em um arquivo de origem C com apenas uma matriz de caracteres definida contendo o conteúdo do arquivo de recursos em formato hexadecimal (para evitar problemas com caracteres maliciosos).Este arquivo fonte gerado automaticamente é simplesmente compilado e vinculado ao projeto.

Deve ser muito fácil implementar o conversor para despejar o arquivo C para cada arquivo de recurso e também escrever algumas funções de fachada para acessar os recursos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top