On Sep 28, 2005, at 10:23 AM, Marshall Clow wrote: a closer look reveals that apparently, when run from the root drive, my program's resources (read from a .rsrc file inside the MachO app bundle) are in a read-only memory area (at least, any attempt to write over loaded resources fails) where they're writable when my program is being launched from a non-boot drive.
Is this expected behavior? Are resources supposed to be in read-only memory and my program is misbehaving?
Yes, this is expected (by some) behavior.
Resource files that are opened readonly for you (like ones in your bundle) are mapped into your address space (read only), rather than being read into memory. This means that you can't go poking into the resources, (like PowerPlant did with it's font handling). It also means that any alignment guarantees that you might expect are null and void (things like handles being aligned on 16 byte boundaries - handy for Altivec, say).
If the file can't be mapped into your address space, then the resource file is opened "normally", and resources are read into memory as you request them.
http://developer.apple.com/documentation/Performance/Conceptual/FileSystem/Articles/MappingFiles.html
Mapping Resource Files Mapping your data fork-based resource files into memory is often a good idea. Resource files typically contain frequently-used data that your application needs to operate. Because of its usefulness, Mac OS X includes a mechanism to map resources automatically. To enable this mechanism, add the following lines to your Info.plist file:
<key>CSResourcesFileMapped</key> |
| <true/> |
|
|
The CFBundle resource file functions (CFBundleOpenBundleResourceMap and CFBundleOpenBundleResourceFiles) check for the CSResourcesFileMapped key before opening a resource file. If this key is present and set to true, the functions map the resource file into memory. The resource data is mapped read-only, so you cannot write to the file or any of its resources directly. For example, the following will cause an memory access exception if the PICT resource comes from a mapped resource file:
PicHandle picture = (PicHandle)GetResource(‘PICT’, 128); |
| (**picture).rect = myRect; // crash here attempting to write |
| // to read-only memory |
|
|
This is now the default. To defeat it and have non-mapped resource files, set
<key>CSResourcesFileMapped</key> |
| <false/> |
in your Info.plist.
Chris |