之前分析了Qt Rcc 资源编译的实现,那么接下来就利用已有的代码,制作一个我们需要的资源编译器吧。
新建一个控制台工程,名为SimpleRcc,首先移植出关键函数:
void printAsciiHex(quint8 c,string& sOut)
{
quint8 cc[5];
cc[0] = '0';
cc[1] = 'x';
cc[2] = '0';
cc[3] = '\0';
cc[4] = '\0';
if (c < 16) {
cc[2] = (digits[c]);
}
else {
cc[2] = (digits[c >> 4]);
cc[3] = (digits[c & 0xf]);
}
static UInt64 iii = 0;
//printf("%s,", cc);
if (iii != 0)
sOut += ",";
sOut += (char*)cc;
//strcat(pNewData,(char*)cc);
if (iii % 16 == 0 && iii != 0)
{
//printf("\n");
//strcat(pNewData,"\r\n");
sOut += "\n";
}
iii++;
}
很明显,将char字符转为Ascii,然后保存进std::string中。
当然,这还不够,下面列出完整的代码,关键代码都有了,不再说细节:
// SimpleRcc.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <STDIO.H>
#include <STDLIB.H>
#include <string.h>
#include <Shlwapi.h>
#include <string>
using namespace std;
typedef signed char qint8; /* 8 bit signed */
typedef unsigned char quint8; /* 8 bit unsigned */
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
const char * const digits = "0123456789abcdef";
void printAsciiHex(quint8 c, string& sOut);
int _tmain(int argc, _TCHAR* argv[])
{
printf("本程序将二进制文件或文本文件编译成16进制字节数组,以便静态编译到程序内部\n");
char sInPutFileNames[500];
printf("请输入要编译的文件名称:\n");
scanf("%s", sInPutFileNames);
char sCurrentDir[MAX_PATH];
GetCurrentDirectoryA(MAX_PATH, sCurrentDir);
strcat(sCurrentDir, "\\");
strcat(sCurrentDir, sInPutFileNames);
if (!PathFileExistsA(sCurrentDir))
{
printf("文件不存在\n");
return 0;
}
FILE* fp = fopen(sCurrentDir, "rb");
if (fp == NULL)
{
printf("打开文件失败\n");
return 0;
}
fseek(fp, SEEK_SET, SEEK_END);
long iFileLen = ftell(fp);
fseek(fp, SEEK_SET, SEEK_SET);
char* data = new char[iFileLen];
fread(data, 1, iFileLen, fp);
fclose(fp);
char sVarName[MAX_PATH];
char delims[] = ".";
char *result = NULL;
result = strtok(sInPutFileNames, delims);
while (result != NULL)
{
strcpy(sVarName, result);
break;
result = strtok(NULL, delims);
}
string sOut = "unsigned long resource_data_";
sOut += sVarName;
sOut += "_length = ";
char sDataLen[100];
_itoa(iFileLen, sDataLen, 10);
sOut += sDataLen;
sOut += ";\r\nstatic const unsigned char resource_data_";
sOut += sVarName;
sOut += "[] = {\n";
for (int i = 0; i<iFileLen; i++)
{
printAsciiHex(data[i], sOut);
}
//printf("}\n");
sOut += "\r\n};\r\n";
char sOutFileName[MAX_PATH];
strcpy(sOutFileName, sVarName);
strcat(sOutFileName, "_out.cpp");
FILE* fpNew = fopen(sOutFileName, "w");
if (fpNew == NULL)
{
printf("无法写入文件:%s\n", sOutFileName);
goto POS_end;
}
fwrite(sOut.c_str(), 1, sOut.length(), fpNew);
fclose(fpNew);
POS_end:
delete []data;
printf("处理完成\n");
return 0;
}
void printAsciiHex(quint8 c,string& sOut)
{
quint8 cc[5];
cc[0] = '0';
cc[1] = 'x';
cc[2] = '0';
cc[3] = '\0';
cc[4] = '\0';
if (c < 16) {
cc[2] = (digits[c]);
}
else {
cc[2] = (digits[c >> 4]);
cc[3] = (digits[c & 0xf]);
}
static UInt64 iii = 0;
//printf("%s,", cc);
if (iii != 0)
sOut += ",";
sOut += (char*)cc;
//strcat(pNewData,(char*)cc);
if (iii % 16 == 0 && iii != 0)
{
//printf("\n");
//strcat(pNewData,"\r\n");
sOut += "\n";
}
iii++;
}
我用VS2013编译通过,下面测试编译一个png图片到EXE中,
运行SimpleRcc.exe,输入11.png,则对应生成了一个11_out.cpp,
下面我用利用这个11_out.cpp,把png编译进exe中去。
新建控制台程序,把11_out.cpp添加到项目中,main.cpp代码如下:
#include <iostream>
#include <windows.h>
#include <string>
#include "11_out.cpp"
using namespace std;
int main()
{
printf("--begin\n");
printf("--resource_data_11_length:%d\n",resource_data_11_length);
FILE* fp = fopen("out.png","wb");
if(fp == NULL)
{
printf("open fail\n");
return 0;
}
fwrite(resource_data_11,1,resource_data_11_length,fp);
fclose(fp);
printf("--end\n");
return 0;
}
运行生成的exe文件(main_bcc.exe),可以看到,一运行,便生成了out.png,打开此png一看,也是正确的。
工程源码地址
http://download.csdn.net/detail/hats8888/9738751