5

The only way I know how to do this is to convert the file into a C source file with a single byte/char array containing the contents of the resource file in hex.

Is there a better or easier way to do this?

theanine
  • 986
  • 3
  • 10
  • 21
  • 2
    Hopefully, you'll be aware that the answer to this problem depends **entirely** on the specifics of the toolchain you're using (compiler, linker, executable format, etc.). So you'd do well to add as much detail as possible to your question. – Oliver Charlesworth Apr 05 '12 at 22:38
  • @OliCharlesworth: Yea, good point. I'm using the GNU Arm Toolchain (arm-elf-gcc). – theanine Apr 05 '12 at 22:40
  • It's worth noting that I was really hoping for a _portable_ answer, so this question will actually be more useful to others who find it. – theanine Apr 05 '12 at 22:48
  • The most portable solution is the one you already have. – Carl Norum Apr 05 '12 at 23:04
  • Here is a link to a program that says it converts binary files to C/C++ header. I can't vouch for it though since I haven't used it myself. http://sourceforge.net/projects/bin2header/ – Brian Swift Apr 05 '12 at 23:30
  • Seems strange to me that such an old low-level language has no way to compile or link binaries along with the source code which will use them. – Georgina Davenport May 14 '21 at 05:36
  • There have been hacky, non-portable ways of embedding binary data in source or linker files for decades. There is [a proposal for an `#embed` preprocessor directive](https://thephd.dev/finally-embed-in-c23) to support this in a standardized cross-platform way for C23. Keep your fingers crossed. – Dour High Arch Sep 03 '22 at 22:00

3 Answers3

3

Here's a nice trick I use with a gcc-arm cross compiler; including a file through an assembly language file. In this example it's the contents of the file public_key.pem I'm including.

pubkey.s

 .section ".rodata"
 .globl pubkey
 .type pubkey, STT_OBJECT
pubkey:
 .incbin "public_key.pem"
 .byte 0
 .size pubkey, .-pubkey

corresponding pubkey.h

#ifndef PUBKEY_H
#define PUBKEY_H
/*
 * This is a binary blob, the public key in PEM format,
 * brought in by pubkey.s
 */
extern const char pubkey[];

#endif // PUBKEY_H

Now the C sources can include pubkey.h, compile the pubkey.s with gcc and link it into your application, and there you go. sizeof(pubkey) also works.

blueshift
  • 6,742
  • 2
  • 39
  • 63
  • 3
    How does sizeof work? Isn't sizeof evaluated at compile time, where the contents of pubkey.s won't even be considered? EDIT: Did you mean strlen? – thenickdude Nov 21 '14 at 07:10
  • @thenickdude [`.size`](https://sourceware.org/binutils/docs/as/Size.html#Size) is probably doing that trick. – Daniel Jour Oct 30 '19 at 20:21
  • ok, doesn't work for me, I had to specify the size in a "variable": `pubkey_size: .int (. - pubkey)` directly after the `.size`; and of course `.globl pubkey_size` and `.type pubkey_size, STT_OBJECT`. Used via `extern const int pubkey_size;` – Daniel Jour Nov 01 '19 at 18:57
2

The way you've described is the best/easiest/most portable. Just write a quick tool (or find an existing one) to generate the C files for you. And make sure you make correct use of the const (and possibly static) keywords when you do it or your program will waste large amounts of memory.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
0

I needed something like this a while ago and I created a tool for this. It's a python tool called mkcres (https://github.com/jahnf/mkcres) and I put it on github.

  • Although documentation is lacking a little, there are examples on how to integrate it into a build process with CMake or plain make files.
  • Takes a .json file as resource file generation configuration
  • It can detect changes on resource files and automatically regenerate the corresponding C files if necessary.
  • Downside: You'll need python (2 or 3)
  • Upside: Not compiler specific, should work with every C/C++ compiler.
Jahn
  • 103
  • 1
  • 8