将数据嵌入C ++程序
时间:2020-03-05 18:56:02 来源:igfitidea点击:
我有一个使用SQLite的C ++程序。我想将SQL查询存储在一个单独的文件中-纯文本文件,而不是源代码文件-而是将该文件像资源一样嵌入到可执行文件中。
(它必须在Linux上运行,因此就我所知,我无法将其存储为实际资源,尽管如果是Windows,那将是完美的。)
有什么简单的方法可以做到这一点,还是有效地要求我为Linux编写自己的资源系统? (很容易,但是会花费更长的时间。)
解决方案
回答
使用宏。从技术上讲,该文件将是源代码文件,但看起来不是这样。
例子:
//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来完成另一项工作并完成它。
回答
这有点丑陋,但我们始终可以使用以下方法:
const char *query_foo = #include "query_foo.txt" const char *query_bar = #include "query_bar.txt"
其中query_foo.txt将包含带引号的查询文本。
回答
我们始终可以编写一个小的程序或者脚本,以将文本文件转换为头文件并在构建过程中运行它。
回答
我已经看到可以通过将资源文件转换为C源文件来完成此工作,其中仅定义了一个char数组,该数组包含十六进制格式的资源文件的内容(以避免出现恶意字符问题)。然后,可以自动编译此自动生成的源文件并将其链接到项目。
实现转换器为每个资源文件转储C文件以及编写一些用于访问资源的Facade函数应该非常容易。
回答
我们可以使用objcopy将文件的内容绑定到程序可以使用的符号。例如,请参阅此处以获取更多信息。
回答
这是我们用于跨平台文件嵌入的示例。
这非常简单,但可能会为我们工作。
我们可能还需要在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; }