Question

J'ai un programme C ++ qui utilise SQLite. Je souhaite stocker les requêtes SQL dans un fichier séparé - un fichier en texte brut, pas un fichier de code source -, mais intégrer ce fichier dans le fichier exécutable comme une ressource.

(Ceci doit fonctionner sous Linux, je ne peux donc pas le stocker en tant que ressource réelle pour autant que je sache, bien que ce serait parfait s'il s'agissait de Windows.)

Existe-t-il un moyen simple de le faire, ou faudra-t-il effectivement que je crée mon propre système de ressources pour Linux? (Facilement possible, mais cela prendrait beaucoup plus de temps.)

Était-ce utile?

La solution

Vous pouvez utiliser objcopy pour lier le contenu du fichier à un symbole que votre programme peut utiliser. Voir, par exemple, ici pour plus d'informations.

Autres conseils

Vous pouvez toujours écrire un petit programme ou script pour convertir votre fichier texte en un fichier d'en-tête et l'exécuter dans le cadre de votre processus de construction.

Utilisez des macros. Techniquement, ce fichier serait un fichier code source , mais il ne ressemblerait pas à ceci. Exemple:

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

Plus tard, vous pourrez effectuer toutes sortes d’autres traitements sur ce fichier, en vous disant que vous voudriez avoir un tableau et une carte de hachage, vous pouvez redéfinir Q pour faire un autre travail et en finir.

Voici un exemple que nous avons utilisé pour l’intégration de fichiers multiplate-forme. C'est assez simpliste, mais cela fonctionnera probablement pour vous.

Vous devrez peut-être également modifier le mode de traitement des sauts de ligne dans la fonction 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;
}

C'est un peu moche, mais vous pouvez toujours utiliser quelque chose comme:

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

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

Où query_foo.txt contient le texte de requête cité.

J'ai constaté que cela se faisait en convertissant le fichier de ressources en un fichier source C avec un seul tableau de caractères défini contenant le contenu du fichier de ressources au format hexadécimal (pour éviter les problèmes de caractères malveillants). Ce fichier source généré automatiquement est ensuite simplement compilé et lié au projet.

Il devrait être assez facile d'implémenter le convertisseur pour vider le fichier C pour chaque fichier de ressources, ainsi que pour écrire certaines fonctions de façade permettant d'accéder aux ressources.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top