一个做到这一点的最简单的方法就是在您建立一个小型的,可移植的C程序,读取资源和生成包含资源数据和实际资源数据的长度,数组的C文件不变的字符文字。这将完全独立于平台,但应仅用于相当小的资源。对于较大的资源,您可能不希望将这些文件嵌入到您的程序中。
对于资源“foo”的,所生成的C文件“foo.c的”将包含:
const char foo[] = { /* bytes of resource foo */ };
const size_t foo_len = sizeof(foo);
要由C访问资源++,则在任一页眉或cpp文件声明如下两个符号他们用在:
extern "C" const char foo[];
extern "C" const size_t foo_len;
要在构建产生foo.c
,你需要一个目标C程序(称之为embedfile.c),你需要使用ADD_CUSTOM_COMMAND命令来调用这个程序:
add_executable(embedfile embedfile.c)
add_custom_command(
OUTPUT foo.c
COMMAND embedfile foo foo.rsrc
DEPENDS foo.rsrc)
然后,在需要“foo”资源的目标的源列表上包含foo.c
。您现在可以访问“foo”的字节。
程序embedfile.c是:
#include <stdlib.h>
#include <stdio.h>
FILE* open_or_exit(const char* fname, const char* mode)
{
FILE* f = fopen(fname, mode);
if (f == NULL) {
perror(fname);
exit(EXIT_FAILURE);
}
return f;
}
int main(int argc, char** argv)
{
if (argc < 3) {
fprintf(stderr, "USAGE: %s {sym} {rsrc}\n\n"
" Creates {sym}.c from the contents of {rsrc}\n",
argv[0]);
return EXIT_FAILURE;
}
const char* sym = argv[1];
FILE* in = open_or_exit(argv[2], "r");
char symfile[256];
snprintf(symfile, sizeof(symfile), "%s.c", sym);
FILE* out = open_or_exit(symfile,"w");
fprintf(out, "#include <stdlib.h>\n");
fprintf(out, "const char %s[] = {\n", sym);
unsigned char buf[256];
size_t nread = 0;
size_t linecount = 0;
do {
nread = fread(buf, 1, sizeof(buf), in);
size_t i;
for (i=0; i < nread; i++) {
fprintf(out, "0x%02x, ", buf[i]);
if (++linecount == 10) { fprintf(out, "\n"); linecount = 0; }
}
} while (nread > 0);
if (linecount > 0) fprintf(out, "\n");
fprintf(out, "};\n");
fprintf(out, "const size_t %s_len = sizeof(%s);\n\n",sym,sym);
fclose(in);
fclose(out);
return EXIT_SUCCESS;
}
这看起来就像一个非常优雅的平台独立解决方案+1。我会试试看。然而,关于我最初忘记提及的东西有一个小小的倒台(参见我的编辑)。如果我将这个解决方案整合到项目中,并尝试对其进行交叉编译,那么在尝试执行embedfile时会遇到麻烦,因为该可执行文件将针对ARM进行编译,并且我将尝试在x86上执行它。我想我可以为我的主机平台分别编译'embedfile'并将其安装到我的路径中。稍微不方便,但我只需要做一次。 – 2012-08-05 19:47:20
@SchighSchagh这可能是CMake的标志,但我目前没有很多交叉编译的经验。如果您知道解释器在感兴趣的主机平台上可用,则可以使用Python或Perl等语言轻松重写embedfile。 – sfstewman 2012-08-05 19:59:26
@SchighSchagh:你可能想看看这个:http://www.cmake.org/Wiki/CMake_Cross_Compiling#Using_executables_in_the_build_created_during_the_build – sfstewman 2012-08-05 20:02:40