2008-09-16 10 views
17

Ich habe ein C++ - Programm, das SQLite verwendet. Ich möchte die SQL-Abfragen in einer separaten Datei speichern - eine Nur-Text-Datei, nicht eine Quellcodedatei - aber diese Datei in die ausführbare Datei wie eine Ressource einbetten.Daten in ein C++ - Programm einbetten

(Dies hat unter Linux laufen zu lassen, also kann ich es nicht als eine tatsächliche Ressource speichern, soweit ich weiß, aber das wäre perfekt, wenn es für Windows ist.)

Gibt es eine einfache Möglichkeit, um es zu tun, oder wird es tatsächlich erfordern, dass ich mein eigenes Ressourcensystem für Linux schreibe? (Leicht möglich, aber es würde viel länger dauern.)

Antwort

24

Sie können objcopy verwenden, um den Inhalt der Datei an ein Symbol zu binden, das von Ihrem Programm verwendet werden kann. Siehe zum Beispiel here für weitere Informationen.

+0

Schön! Vielen Dank! –

3

Verwenden von Makros. Technisch wäre diese Datei Quellcode Datei, aber es würde nicht so aussehen. Beispiel:

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

auf Sie später von der gleichen Datei, die alle möglichen anderen Verarbeitung auf dieser Datei tun könnte, sagen Sie würden wollen Array haben und eine Hash-Matrix von ihnen, könnten Sie Q neu definieren eine andere zu tun Job und damit fertig sein.

1

Es ist etwas hässlich, aber man kann immer so etwas wie verwenden:

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

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

Wo query_foo.txt die zitierte Abfragetext enthalten würde.

+1

was, wenn es eine neue Zeile enthält? –

+0

Es wird nicht für eine neue Zeile funktionieren. – SmallChess

3

Sie können immer ein kleines Programm oder Skript schreiben Sie Ihre Text-Datei in eine Header-Datei und führen Sie es als Teil des Build-Prozesses zu konvertieren.

0

Ich habe gesehen, dass dies getan wurde, indem die Ressourcendatei in eine C-Quelldatei mit nur einem Char-Array konvertiert wurde, das den Inhalt der Ressourcendatei in einem hexadezimalen Format enthält (um Probleme mit bösartigen Zeichen zu vermeiden). Diese automatisch erzeugte Quelldatei wird dann einfach kompiliert und mit dem Projekt verknüpft.

Es sollte ziemlich einfach sein, den Konverter zu implementieren, um eine C-Datei für jede Ressourcendatei abzulegen, auch um einige Fassadenfunktionen für den Zugriff auf die Ressourcen zu schreiben.

2

Hier ist ein Beispiel für die plattformübergreifende Einbettung von Dateien. Es ist ziemlich simpel, aber wird wahrscheinlich für Sie arbeiten.

Unter Umständen müssen Sie auch ändern, wie es Zeilenvorschübe in der escapeLine Funktion der Verarbeitung.

#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; 
}