【问题标题】:script/tool to convert file to C/C++ source code array将文件转换为 C/C++ 源代码数组的脚本/工具
【发布时间】:2012-02-01 04:37:21
【问题描述】:

我需要一个脚本/工具来读取二进制文件并输出 C/C++ 源代码数组(代表文件内容)。有吗?


(这个问题之前被删除了。我把这个问题放回去了,因为它很有价值。我在谷歌上搜索这个并没有找到任何东西。当然自己编写代码很简单,但我会保存一些如果我能找到这么简单的脚本,几分钟就可以了。因此它很有价值。

这个问题也有很多反对票,没有太多解释。请在投反对票之前发表评论,为什么您认为这没有价值或价值不高。

这个问题也让我对我所问的问题产生了很多困惑。如果有不清楚的地方,请询问。我真的不知道如何说得更清楚。有关示例,请参阅答案。

另外(在这里提出问题之后),我已经有了几个答案。我只想将它们(再次)放在这里/链接它们,因为我认为它可能对其他搜索此内容的人有用。)

【问题讨论】:

  • 可能人们明白你想要某种反编译器或类似的东西。您可以将其改写为“读取二进制文件并输出初始化为文件内容的数组的 C/C++ 声明”或类似的内容。

标签: c binary


【解决方案1】:

在 Debian 和其他 Linux 发行版上默认安装(连同 vimxxd 工具,如果使用 -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>

是你要转成C头文件的文件名,

是头文件名,是你希望数组有的名字。

上面的单行 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 位值。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-09-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-05
          • 2010-10-28
          • 2011-01-09
          相关资源
          最近更新 更多