gpt4 book ai didi

c - 在静态库中嵌入资源 - C/C++

转载 作者:行者123 更新时间:2023-11-30 17:03:38 25 4
gpt4 key购买 nike

我正在学习如何仅使用终端创建库。是否有可能(我怀疑可能不可能)将资源(例如图像、文本、API key 等)放入静态链接的存档文件中,就像在 NSBundle 中一样?我如何引用这些资源?

最佳答案

在 POSIX 系统上,您有一个几乎标准的 shell sh ,四个非常有用的 shell 实用程序,名为 rm , printf , od ,和sed .

假设您希望使用包含二进制文件 foo.bar 内容的 const unsigned char blob[] 数组创建文件 foo.c:

export LANG=C LC_ALL=C
rm -f foo.c
printf 'const unsigned char blob[] = {\n' > foo.c
od -A n -t x1 foo.bar | sed -e 's| *\([0-9A-Fa-f][0-9A-Fa-f]\)| 0x\1U,|g; s|^| |' >> foo.c
printf '};\n' >> foo.c

第一行将语言环境设置为C。这确保实用程序使用我们期望的格式,而不是某些本地化变体。

第二行删除可能存在的foo.c。 (如果您将输出直接输出到现有文件而不附加到它,有些 shell 会提示。)如果文件还不存在,-f 会消除任何提示。

第三行和第五行将数组定义附加到 foo.c 文件中。

第四行使用od实用程序将foo.bar的内容输出为十六进制字节。我们使用 sed 在每个十六进制字节前面添加 0x 和附加 U, 使其变得漂亮且漂亮的 C,然后我们在前面添加额外的三个该行的空格(使其缩进四个空格)。

如果您不喜欢这种方法,您可以随时编写自己的实用程序来完成此操作。例如: #包括 #包括 #包括 #包括

#ifndef  DEFAULT_VARNAME
#define DEFAULT_VARNAME "blob"
#endif

#ifndef DEFAULT_STORAGE
#define DEFAULT_STORAGE "const"
#endif

#ifndef DEFAULT_ATTRIBUTES
#define DEFAULT_ATTRIBUTES ""
#endif

#ifndef DEFAULT_INDENT
#define DEFAULT_INDENT " "
#endif

#ifndef DEFAULT_COLUMNS
#define DEFAULT_COLUMNS 16
#endif

int usage(const char *argv0)
{
fprintf(stderr, "\n");
fprintf(stderr, "Usage: %s [ -h | --help ]\n", argv0);
fprintf(stderr, " %s [ OPTIONS ] file [ [ OPTIONS ] file .. ]\n", argv0);
fprintf(stderr, "\n");
fprintf(stderr, "Options:\n");
fprintf(stderr, " -n %-10s Variable name\n", "'" DEFAULT_VARNAME "'");
fprintf(stderr, " -s %-10s Storage type\n", "'" DEFAULT_STORAGE "'");
fprintf(stderr, " -a %-10s Attributes\n", "'" DEFAULT_ATTRIBUTES "'");
fprintf(stderr, " -i %-10s Indentation\n", "'" DEFAULT_INDENT "'");
fprintf(stderr, " -c %-10d Bytes per line\n", (int)DEFAULT_COLUMNS);
fprintf(stderr, "\n");
fprintf(stderr, "This program will output the contents of the specified file(s)\n");
fprintf(stderr, "as C source code.\n");
fprintf(stderr, "\n");
return EXIT_SUCCESS;
}


int main(int argc, char *argv[])
{
const char *storage = DEFAULT_STORAGE;
const char *varname = DEFAULT_VARNAME;
const char *attributes = DEFAULT_ATTRIBUTES;
const char *indent = DEFAULT_INDENT;
size_t columns = DEFAULT_COLUMNS;

FILE *in;
size_t bytes;
int ch, arg;
char dummy;

if (argc < 2)
return usage(argv[0]);

arg = 1;
while (arg < argc) {

if (argv[arg][0] == '-') {
if (argv[arg][1] == 'n') {
if (argv[arg][2] != '\0') {
varname = argv[arg] + 2;
arg++;
continue;
} else
if (arg + 1 < argc) {
varname = argv[arg + 1];
arg += 2;
continue;
}
} else
if (argv[arg][1] == 's') {
if (argv[arg][2] != '\0') {
storage = argv[arg] + 2;
arg++;
continue;
} else
if (arg + 1 < argc) {
storage = argv[arg + 1];
arg += 2;
continue;
}
} else
if (argv[arg][1] == 'a') {
if (argv[arg][2] != '\0') {
attributes = argv[arg] + 2;
arg++;
continue;
} else
if (arg + 1 < argc) {
attributes = argv[arg + 1];
arg += 2;
continue;
}
} else
if (argv[arg][1] == 'i') {
if (argv[arg][2] != '\0') {
indent = argv[arg] + 2;
arg++;
continue;
} else
if (arg + 1 < argc) {
indent = argv[arg + 1];
arg += 2;
continue;
}
} else
if (argv[arg][1] == 'c') {
if (argv[arg][2] != '\0') {
if (sscanf(argv[arg] + 2, " %zu %c", &columns, &dummy) != 1 || columns < 1) {
fprintf(stderr, "%s: Invalid number of bytes per line.\n", argv[arg] + 2);
return EXIT_FAILURE;
}
arg++;
continue;
} else
if (arg + 1 < argc) {
if (sscanf(argv[arg+1], " %zu %c", &columns, &dummy) != 1 || columns < 1) {
fprintf(stderr, "%s: Invalid number of bytes per line.\n", argv[arg + 1]);
return EXIT_FAILURE;
}
arg += 2;
continue;
}
} else
if (!strcmp(argv[arg], "-h") || !strcmp(argv[arg], "--help"))
return usage(argv[0]);
}

in = fopen(argv[arg], "r");
if (!in) {
fprintf(stderr, "%s: %s.\n", argv[arg], strerror(errno));
return EXIT_FAILURE;
}

printf("%s unsigned char %s[] %s= {", storage, varname, attributes);

bytes = 0;
while ((ch = getc(in)) != EOF)
if (bytes++ % columns)
printf(", %3u", (unsigned int)ch);
else
printf("\n%s%3u", indent, (unsigned int)ch);

printf("\n}; /* %zu bytes */\n\n", bytes);

if (ferror(in)) {
fclose(in);
fprintf(stderr, "%s: Read error.\n", argv[arg]);
return EXIT_FAILURE;
}
if (fclose(in)) {
fprintf(stderr, "%s: Delayed read error.\n", argv[arg]);
return EXIT_FAILURE;
}

if (fflush(stdout) || ferror(stdout)) {
fprintf(stderr, "Error writing to standard output.\n");
return EXIT_FAILURE;
}

arg++;
}

return EXIT_SUCCESS;
}

上述代码中唯一的 POSIX 主义是使用 %zu 扫描并打印 size_t

关于c - 在静态库中嵌入资源 - C/C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36098868/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com