将文件转换为 C/C++ 源代码数组的脚本/工具
Posted
技术标签:
【中文标题】将文件转换为 C/C++ 源代码数组的脚本/工具【英文标题】:script/tool to convert file to C/C++ source code array 【发布时间】:2012-02-01 04:37:21 【问题描述】:我需要一个脚本/工具来读取二进制文件并输出 C/C++ 源代码数组(代表文件内容)。有吗?
(这个问题之前被删除了。我把这个问题放回去了,因为它很有价值。我在谷歌上搜索这个并没有找到任何东西。当然自己编写代码很简单,但我会保存一些如果我能找到这么简单的脚本,几分钟就可以了。因此它很有价值。
这个问题也有很多反对票,没有太多解释。请在投反对票之前发表评论,为什么您认为这没有价值或价值不高。
这个问题也让我对我所问的问题产生了很多困惑。如果有不清楚的地方,请询问。我真的不知道如何说得更清楚。有关示例,请参阅答案。
另外(在这里提出问题之后),我已经有了几个答案。我只想将它们(再次)放在这里/链接它们,因为我认为它可能对其他搜索此内容的人有用。)
【问题讨论】:
可能人们明白你想要某种反编译器或类似的东西。您可以将其改写为“读取二进制文件并输出初始化为文件内容的数组的 C/C++ 声明”或类似的内容。 【参考方案1】:在 Debian 和其他 Linux 发行版上默认安装(连同 vim
)xxd
工具,如果使用 -i
选项,它可以做你想做的事:
matteo@teodeb:~/Desktop$ echo Hello World\! > temp
matteo@teodeb:~/Desktop$ xxd -i temp
unsigned char temp[] =
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21,
0x0a
;
unsigned int temp_len = 13;
【讨论】:
啊,太好了!它甚至可以在 MacOSX 中使用。 在 Windows 上将 xxd 集成到 Visual Studio 2013 解决方案中的问题为零。我用this source 唯一的问题可能是,这个数组不是 const (以及长度)。这可能会对微控制器(RAM 与 ROM)产生影响。您可能需要编辑生成的文件。 @TomaszGandor:是的,虽然从我看到的例如AVR 微控制器const
还不够,如果您希望它们留在闪存中,您必须添加供应商特定属性(gcc 中的PROGMEM
);我担心这种情况对于通用工具来说可能过于具体,您可能需要编写一个特定的构建脚本。
@MatteoItalia - 我同意。我已经把它包装好了,所以这是通过| sed 's/unsigned/const unsigned/'
输出的管道,它可以在这一行中说出你需要的任何其他内容。 (我把结果放到一个单独的文件中 - 很容易被覆盖)。【参考方案2】:
如果您在类似 *nix 的系统上,使用 xxd 工具的公认答案很好。对于路径上具有 python 可执行文件的任何系统,这是一个“单线”:
python -c "import sys;a=sys.argv;open(a[2],'wb').write(('const unsigned char '+a[3]+'[] = '+','.join([hex(b) for b in open(a[1],'rb').read()])+';').encode('utf-8'))" <binary file> <header file> <array name>
上面的单行 Python 命令与下面的(更易读的)Python 程序大致相同:import sys
with open(sys.argv[2],'wb') as result_file:
result_file.write(b'const char %s[] = ' % sys.argv[3].encode('utf-8'))
for b in open(sys.argv[1], 'rb').read():
result_file.write(b'0x%02X,' % b)
result_file.write(b';')
【讨论】:
我使用了这个答案,而不是自己写。它缺少很多格式,.h 文件可以使用一些#ifdef 保护来防止多重包含,但它有效。 +1 工作。【参考方案3】:一个简单的工具可以找到here:
#include <stdio.h>
#include <assert.h>
int main(int argc, char** argv)
assert(argc == 2);
char* fn = argv[1];
FILE* f = fopen(fn, "rb");
printf("char a[] = \n");
unsigned long n = 0;
while(!feof(f))
unsigned char c;
if(fread(&c, 1, 1, f) == 0) break;
printf("0x%.2X,", (int)c);
++n;
if(n % 10 == 0) printf("\n");
fclose(f);
printf(";\n");
【讨论】:
您将在字符数组末尾的“”之前有额外的“,” 这不是问题,它可以用 C++ 编译。【参考方案4】:此工具在 C 语言的开发人员命令提示符中编译。它向终端生成输出,显示所创建的“array_name.c”文件中的内容。请注意,某些终端可能会显示“\b”字符。
#include <stdio.h>
#include <assert.h>
int main(int argc, char** argv)
assert(argc == 2);
char* fn = argv[1];
// Open file passed by reference
FILE* f = fopen(fn, "rb");
// Opens a new file in the programs location
FILE* fw = fopen("array_name.c","w");
// Next two lines write the strings to the console and .c file
printf("char array_name[] = \n");
fprintf(fw,"char hex_array[] = \n");
// Declare long integer for number of columns in the array being made
unsigned long n = 0;
// Loop until end of file
while((!feof(f)))
// Declare character that stores the bytes from hex file
unsigned char c;
// Ignore failed elements read
if(fread(&c, 1, 1, f) == 0) break;
// Prints to console and file, "0x%.2X" ensures format for all
// read bytes is like "0x00"
printf("0x%.2X,", (int)c);
fprintf(fw,"0x%.2X,", (int)c);
// Increment counter, if 20 columns have been made, begin new line
++n;
if(n % 20 == 0)
printf("\n");
fprintf(fw,"\n");
// fseek places cursor to overwrite extra "," made from previous loop
// this is for the new .c file. Since "\b" is technically a character
// to remove the extra "," requires overwriting it.
fseek(fw, -1, SEEK_CUR);
// "\b" moves cursor back one in the terminal
printf("\b;\n");
fprintf(fw,";\n");
fclose(f);
fclose(fw);
【讨论】:
【参考方案5】:这是 C 数组生成器 python 源代码的二进制文件,与Albert's answer 中的程序相同。
import sys
from functools import partial
if len(sys.argv) < 2:
sys.exit('Usage: %s file' % sys.argv[0])
print("char a[] = ")
n = 0
with open(sys.argv[1], "rb") as in_file:
for c in iter(partial(in_file.read, 1), b''):
print("0x%02X," % ord(c), end='')
n += 1
if n % 16 == 0:
print("")
print(";")
【讨论】:
【参考方案6】:这个问题很老,但让我建议可以用作替代的简单工具......
您可以使用名为 Fluid 的基于 GUI 的工具。它实际上用于设计 FLTK 工具包的接口,但也可以从二进制文件为 C++ 生成无符号字符数组。从muquit下载。
【讨论】:
【参考方案7】:我检查了所有可用的选项,并决定制作我自己的小程序来进行转换:
https://github.com/TheLivingOne/bin2array/blob/master/bin2array.c
它的运行速度比 bin2c 甚至 xxd 快得多,这对于较大的文件很重要,特别是如果您想将转换嵌入到您的构建系统中。例如。对于我机器上的 50 Mb 文件:
bin2c.py > 20 秒
简单的 Python 脚本 - 大约 10 秒
xxd - 大约 3 秒
bin2array - 大约 0.4 秒
此外,它还可以生成更紧凑的输出并为数组添加对齐方式,以防您想在其中放置 32 位或 64 位值。
【讨论】:
以上是关于将文件转换为 C/C++ 源代码数组的脚本/工具的主要内容,如果未能解决你的问题,请参考以下文章
在 C/C++ 中将 1 位 bmp 文件转换为数组 [关闭]