Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

script/tool to convert file to C/C++ source code array

Tags:

c

binary

I need to include the contents of a binary file in my C/C++ source code as the text for the declaration of an array initialized to the content of the file. I'm not looking to read the file dynamically at runtime. I want to perform the operation once and then use the generated array declaration text.

How can I convert a binary file to the text for the C/C++ declaration of an array which is initialized to the contents of the file?

like image 705
Albert Avatar asked Jan 03 '12 02:01

Albert


4 Answers

On Debian and other Linux distros is installed by default (along with vim) the xxd tool, which, given the -i option, can do what you want:

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;
like image 105
Matteo Italia Avatar answered Nov 20 '22 08:11

Matteo Italia


The accepted answer using xxd tool is nice if you are on a *nix-like system. Here is a "one-liner" for any system that has python executable on the path:

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>

< binary file > is the name of the file you want to turn into a C header, < header file > is the name of the header file, and < array name > is the name you want the array to have.

The above one-line Python command does approximately the same as the following (much more readable) Python program:

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'};')
like image 21
astraujums Avatar answered Nov 20 '22 09:11

astraujums


One simple tool can be found 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");
}
like image 43
Albert Avatar answered Nov 20 '22 08:11

Albert


I checked all available options and decided to make my own little program to do the conversion:

https://github.com/TheLivingOne/bin2array/blob/master/bin2array.c

It works much faster than bin2c and even xxd which is important for larger files, especially if you want to embed the conversion into your build system. E.g. for 50 Mb file on my machine:

bin2c.py > 20 sec

Simple Python scripts - about 10 sec

xxd - about 3 sec

bin2array - about 0.4 sec

Also, it produces much more compact output and adds alignment to the array, in case you want to put 32 or 64 bit values there.

like image 2
Sergey Galin Avatar answered Nov 20 '22 07:11

Sergey Galin