把资源编译进EXE之(二)打造定制的资源编译器

之前分析了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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值