Tutorial 7: File Handles
Last Revised: 6:52 PM 11/8/2000
DevIL has allowed loading from file streams for many releases, but when we
started the Visual Basic and Delphi ports, we realized that we could not
restrict the file streams as being C-style stdio.h FILE pointers, since VB and
Delphi do not use the C stdio library. Our compromise was to use void pointers and
let the caller specify callback functions to work on the void pointer streams. This
method also allows the user to use different file streams in C/C++, such as Windows
handles, or even iostream methods. All image loading in DevIL is abstracted, so
this method works quite well.
Setting Callback Functions
The long-named ilSetFileCallbacks() function simply accepts function pointers for its arguments.
If any argument is NULL, DevIL will generally not crash, but image loading may not function
correctly, so specify correct functions for all arguments. All functions passed need to
use the stdcall calling convention. The functions specified will work on the ILHANDLE
types of file streams you pass ilLoadF (or other file stream functions), so make sure you
change the function pointers with ilSetFileCallbacks() when you change ILHANDLE types.
ILvoid ilSetFileCallbacks(fOpenProc, fCloseProc, fGetcProc, fReadProc, fSeekProc, fTellProc);
Example of setting callbacks
ILHANDLE Open(char *FileName)
return fopen(FileName, "rb");
ilSetFileCallbacks(Open, Close, Getc, Read, Seek, Tell);
Types of Callback Functions
This function will open a file and by the char* parameter it receives and
return an ILHANDLE to the file stream.
This function closes the ILHANDLE file stream passed as its parameter.
This function gets exactly one character from the ILHANDLE passed as its parameter.
This function retrieves a specified number of bytes from the file handle passed to it. It s parameters are (in order): void*, ILint, ILint, ILHANDLE. The void* is the buffer that receives the bytes from the file. The first ILint is the size of the data type. The second ILint is the number of the data types to retrieve. You can just multiply the ILints together to determine the number of bytes to retrieve. The ILHANDLE is the file stream to get the data from.
This function skips around in the file stream (setting the file pointer to a different position). It is the equivalent of fseek. The parameters are: ILHANDLE, ILint, ILint. The ILHANDLE is the file stream to seek in. The first ILint is the number of bytes to skip. The second ILint is the mode to skip with. It uses the C stdio #define's for this: SEEK_SET, SEEK_CUR, SEEK_END. You may need to #define these in your application if they are not already there (e.g. Visual Basic and Delphi users).
This function reports the current position of the file stream's file pointer. It is similar to ftell. The only parameter passed to this function is the ILHANDLE to determine the file pointer from.
You may have problems with file handles if you use the C stdio file-reading and use the MSVC++ compiler.
The Windows Setup tutorial describes how to circumvent this.