[fpc-pascal] Placing binary data (resources) in object files?
Ewald
ewald at yellowcouch.org
Mon Jun 3 18:09:15 CEST 2013
Once upon a time, Anthony Walter said:
> I am trying to come up with an embedded binary resource system and was
> considering placing data in object files when I found this question on
> stack overflow:
> http://stackoverflow.com/questions/4158900/embedding-resources-in-exe-using-gcc
>
>
> I see that it's possible to directly turn any file into an object file
> and reference the memory of that as a resource in a C program using:
>
> extern char binary_foo_bar_start[];
> extern char binary_foo_bar_end[];
>
> My question, is it possible to link extern char in free pascal in a
> way similar to above? Perhaps something similar to:
>
> var binary_foo_bar_start: pointer; external;
>
> {$L foo.bar.o}
>
> Or some permutation of the above?
You can pass an option directly to the link ( add -k--format=binary
-k<binary files you wish to embed> -k--format=default to the fpc command
line), or you could use objcopy.
These two aproaches aren't very portable though, so it is best you write
a script or something that generates code that contains this file.
Something like this:
===php code begin===
<?php
function ObjCopy($file, $name, $outputname = 0)
{
$contents = file_get_contents($file);
$size = strlen($contents);
if ($outputname === 0)
$outputname = "blob_$name.o";
$invalidsymbolcharacters = array('!', '@', '#', '$', '%', '^', '&',
'*', '(', ')', '_', '+', '-', '=', '[', ']', '{', '}', '\'', '\\', '"',
'|', ';', ':', ',', '.', '/', '<', '>', '?', '`', '~');
$name = str_replace($invalidsymbolcharacters, '_', $name);
$data = '';
for ($cnt=0; $cnt < $size; $cnt++)
$data.= '0x'.dechex(ord($contents[$cnt])).',';
$data = substr($data, 0, -1);
$tmpfile = "#include <cstddef>\n";
$tmpfile.= "extern \"C\" const size_t _binary_{$name}_size = $size;\n";
$tmpfile.= "extern \"C\" const char _binary_{$name}_start[] =
{{$data}};\n";
$tmpfile.= "extern \"C\" const char* _binary_{$name}_end =
&_binary_{$name}_start[0] + $size-1;\n";
fwrite($handle = popen("gcc -o '$outputname' -c -x c++ - -O3 -Wall
-pipe", 'w'), $tmpfile);
pclose($handle);
}
?>
===php code end===
Usage: `ObjCopy('binaryinputfile', 'symol name',
'outputobjectfile.o');`. Then add `-koutputobjectfile.o` to the command
line of fpc. Next you can define your symbols in pascal as follows:
{$escapedpascalname}_start: array[0..<$length-1>] of cuint8; external
name '_binary_{$escapedname}_start';
{$escapedpascalname}_end: array[<1-$length>."..0] of cuint8; external
name '_binary_{$escapedname}_end';
{$escapedpascalname}_size: array[0..0] of cuint8; external name
'_binary_{$escapedname}_size';
Where {$escapedpascalname} is the name you gave as the second argument
to the function above. `$length` is the length of the original data in
bytes. To read the size, just use `csize_t(@{$escapedpascalname}_size)`.
Note that the above is a very quick draft (kind of a quickfix for some
other project -- but is works) and thus contains errors and lacks error
checking. Use at your own risk ;-)
PS: Sorry about the php code there; I know it's not the php mailing
list, but my buildtool happens to be written in php ;-)
--
Ewald
More information about the fpc-pascal
mailing list