abcdef12
asked on
Including A Binary File At compile Time.
Hi,
How the hell do I #Include a binary file at compile time, so that the binary data will be
contained in my final .EXE ?
I don't want to load the binary data into memory at run time.
In other words, I want my code AND data to be completely contained within one
EXE file.
I realize I could do the following to include the data in the final EXE,
but what a laborious task!
unsigned char data[256] = { 4,6,231,76,253,90,22, ... etc... 33,55,121 } ;
NB: I'm using Borland C++.
Can anyone please help?
james.kearns@xtra.co.nz
How the hell do I #Include a binary file at compile time, so that the binary data will be
contained in my final .EXE ?
I don't want to load the binary data into memory at run time.
In other words, I want my code AND data to be completely contained within one
EXE file.
I realize I could do the following to include the data in the final EXE,
but what a laborious task!
unsigned char data[256] = { 4,6,231,76,253,90,22, ... etc... 33,55,121 } ;
NB: I'm using Borland C++.
Can anyone please help?
james.kearns@xtra.co.nz
Do you want a program to convert a binary file into
unsigned char data[256] = { 4,6,231,76,253,90,22, ... etc... 33,55,121 } ;
?
unsigned char data[256] = { 4,6,231,76,253,90,22, ... etc... 33,55,121 } ;
?
The other way is to put it as a userdefined resource in your .rc file. Take a look at this for reference:
http://www.inprise.com/devsupport/borlandcpp/ti_list/TI1040.html
This is an example of how to put a wav file into your program. The wav file is a bunch of binary data that is included in your .rc (resource file) at compile time. You can do this same technique if you just have generalized binary data. Once its loaded into memory (at run time) you can move it into a structure, or do whatever you want with it.
In the example they are loading this thing to something called sound. You could make a union of the LPSTR (i made it LPSTR) and your other structure. That would let you reference the data as a char * for loading, and your structure when you actually need to reference it.
At runtime you just load the appropriate resource....
http://www.inprise.com/devsupport/borlandcpp/ti_list/TI1040.html
This is an example of how to put a wav file into your program. The wav file is a bunch of binary data that is included in your .rc (resource file) at compile time. You can do this same technique if you just have generalized binary data. Once its loaded into memory (at run time) you can move it into a structure, or do whatever you want with it.
In the example they are loading this thing to something called sound. You could make a union of the LPSTR (i made it LPSTR) and your other structure. That would let you reference the data as a char * for loading, and your structure when you actually need to reference it.
At runtime you just load the appropriate resource....
ASKER
Attn: Ozo,
Yea, that would be one way of doing it. I never thought of that. ie. converting the binary file into an ascii text file, commas and all and using an #Include directive.
If you have some source code or EXE , I'd certainly be interested.
Many Thanks
Attn: Duneram,
I'll check out http://www.inprise.com/devsupport/borlandcpp/ti_list/TI1040.html
and get back to you.
Many Thanks.
Yea, that would be one way of doing it. I never thought of that. ie. converting the binary file into an ascii text file, commas and all and using an #Include directive.
If you have some source code or EXE , I'd certainly be interested.
Many Thanks
Attn: Duneram,
I'll check out http://www.inprise.com/devsupport/borlandcpp/ti_list/TI1040.html
and get back to you.
Many Thanks.
Okay. Good luck with it
abc: this is how you would go about doing it via the RC file way. Its very painless:
129 TEST1 DISCARDABLE "res\\e3.wav"
That's how you would implement the method of including the binary file in your resource file.
You would insert a line like that of above which would at compile time, automatically include the contents of the file in one easy shot.
When you want to load your resource you would load #129. You could always use #define ID_IDENT 129 to make it a bit more readable but thats basically the way to do it without having to do fancy coding.
129 TEST1 DISCARDABLE "res\\e3.wav"
That's how you would implement the method of including the binary file in your resource file.
You would insert a line like that of above which would at compile time, automatically include the contents of the file in one easy shot.
When you want to load your resource you would load #129. You could always use #define ID_IDENT 129 to make it a bit more readable but thats basically the way to do it without having to do fancy coding.
the res\\e3.wav implies the wav file is sitting in a sub dir relative to the rc file. the wav file could be anywhere you specify.
ASKER
Attn: Duneram,
I'm relatively new to C programming, so haven't delved into resource files etc. yet.
At this stage, writing a small program which reads in my binary file and creates an equivalent text file which I can #Include ( ie. Preprocessor Directive ) in my source code at compile time, seems a bit simpler.
However, if under a DOS environement, this .RC/.RES business does create one, and only one file, ie. an EXE which includes my data, then I'd have to concede that you've answered my question. I'd have to give you the points.
I'm probably getting a bit ahead of myself, by expecting to be able to do things that I haven't yet learnt about.
Although, an " #Include bin " directive was available in my Hisoft Devpac Assembler for the Atari ST, I expected to find one in a C language compiler for a PC.
Regards, ABCDEF12
I'm relatively new to C programming, so haven't delved into resource files etc. yet.
At this stage, writing a small program which reads in my binary file and creates an equivalent text file which I can #Include ( ie. Preprocessor Directive ) in my source code at compile time, seems a bit simpler.
However, if under a DOS environement, this .RC/.RES business does create one, and only one file, ie. an EXE which includes my data, then I'd have to concede that you've answered my question. I'd have to give you the points.
I'm probably getting a bit ahead of myself, by expecting to be able to do things that I haven't yet learnt about.
Although, an " #Include bin " directive was available in my Hisoft Devpac Assembler for the Atari ST, I expected to find one in a C language compiler for a PC.
Regards, ABCDEF12
Under Windows, the RC method creates a RES file which is then attached to your EXE. The windows method is painless and easy and requires virtually no effort on your part. If the binary file were to change (ever) the next time you built the EXE it would automatically use the changed version of the binary file. As far as the end user is concerned, there is only one EXE. The file you would ship to your customers would be the sole EXE file. The RES file is like an OBJ (compiled, ready for the linker).
Under DOS I do not think the RC method will work for you, so OZO's method would be a better solution.
Good LUck
Under DOS I do not think the RC method will work for you, so OZO's method would be a better solution.
Good LUck
OR... you could write a program to tack on the binary file to the end of your executable. Like a self-extracting executable.
We use this tecnique with several binary files.
We use this tecnique with several binary files.
ASKER
Attn: Duneram, Marvinm and Ozo.
Id like to thank you all for your help and split these points amongst the 3 of you.
How do I do that?
Messages follow for Duneram and Marvinm:
Attn: Marvinm,
Correct me here if I'm wrong, but your method would mean that I couldn't create a pointer
to this data because at compile time it doesn't even exist.
At run time, my program would have to actually load itself in, from the "start of data" or "end of program +1".
In other words, I would have to treat it as if it was a completely separate file.
I,d also have to know exactly where in the EXE this data was.( ie. EXE length minus binary data length ).
I quite like the idea.
Regards, ABCDEF12
Attn: Duneram,
I should have advised at the start, that I was working in a DOS environement.
My apologies.
Regards, ABCDEF12
Id like to thank you all for your help and split these points amongst the 3 of you.
How do I do that?
Messages follow for Duneram and Marvinm:
Attn: Marvinm,
Correct me here if I'm wrong, but your method would mean that I couldn't create a pointer
to this data because at compile time it doesn't even exist.
At run time, my program would have to actually load itself in, from the "start of data" or "end of program +1".
In other words, I would have to treat it as if it was a completely separate file.
I,d also have to know exactly where in the EXE this data was.( ie. EXE length minus binary data length ).
I quite like the idea.
Regards, ABCDEF12
Attn: Duneram,
I should have advised at the start, that I was working in a DOS environement.
My apologies.
Regards, ABCDEF12
abcdef12,
Yes, you would have to read from your executable file. This is how we combine our data and executable. Open the executable file, append a unique identifier indicating the type of data stored in the block, append the length of the binary data being added as an integer (we do it as a binary integer, but for portability you might want to store as a string), then append the data. Repeat for all the blocks you have to add. Then the last thing to append to the file is the size of the executable. This will give you the offset to start reading you data. Then to get at you data, first read the last 4 bytes (in our case) or the length of your length string (probably 10 characters should do). Now move to that position in the file and read your data. Hope this helps. - mm
Yes, you would have to read from your executable file. This is how we combine our data and executable. Open the executable file, append a unique identifier indicating the type of data stored in the block, append the length of the binary data being added as an integer (we do it as a binary integer, but for portability you might want to store as a string), then append the data. Repeat for all the blocks you have to add. Then the last thing to append to the file is the size of the executable. This will give you the offset to start reading you data. Then to get at you data, first read the last 4 bytes (in our case) or the length of your length string (probably 10 characters should do). Now move to that position in the file and read your data. Hope this helps. - mm
I don't think you can split points, but you could reject the question and give it to the person you choose. I have seen people post a 'pseudo question' directed directly to someone to 'divy up points', but if you want to pursue this you could try asking over in https://www.experts-exchange.com/topics/experts-exchange/
I think you need to delete the question or change the points down to a smaller number
or post a message in customer service to have them delete the question.
If you do nothing eventually the question will be 'autograded'
or post a message in customer service to have them delete the question.
If you do nothing eventually the question will be 'autograded'
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
I bumped into this solution page looking for a way to produce self-extracting archives on unix w/o using shar. As I subsequently found the solution, I thought I'd post it here in case someone repeats the same search as I.
from http://linux.org.mt/article/selfextract
cat sfx-header mypackage-1.2.3.tgz > mypackage-1.2.3.sh
the sfx-header file:
#!/bin/sh
echo ""
echo "MyPackage v99.99 - extracting archive... please wait"
echo ""
SKIP=`awk '/^__ARCHIVE_FOLLOWS__/ { print NR + 1; exit 0; }' $0`
# take the archive portion of this file and pipe it to tar
tail +$SKIP $0 | tar xz
exit 0
__ARCHIVE_FOLLOWS__
from http://linux.org.mt/article/selfextract
cat sfx-header mypackage-1.2.3.tgz > mypackage-1.2.3.sh
the sfx-header file:
#!/bin/sh
echo ""
echo "MyPackage v99.99 - extracting archive... please wait"
echo ""
SKIP=`awk '/^__ARCHIVE_FOLLOWS__/ { print NR + 1; exit 0; }' $0`
# take the archive portion of this file and pipe it to tar
tail +$SKIP $0 | tar xz
exit 0
__ARCHIVE_FOLLOWS__
ASKER