This paper describes input/output low level implementation in the Visual Eiffel.
1. General issues
2. Attaching to specified input/output
2.1. Executable file attaching
2.2. DLL attaching
2.3. Possible problems
3. Visual Eiffel IO API
3.1. Basic input/output API
3.1.1. IOAttach
3.1.2. IODetach
3.1.3. _io_get_boolean
3.1.4. _io_get_character
3.1.5. _io_get_double
3.1.6. _io_get_int
3.1.7. _io_get_newline
3.1.8. _io_get_real
3.1.9. _io_get_line
3.1.10. _io_put_string
3.1.11. _io_put_int
3.1.12. _io_put_real
3.1.13. _io_put_double
3.1.14. _io_put_char
3.1.15. _io_put_boolean
3.1.16. _io_put_newline
3.1.17. printError
3.2. IO DLL API
3.2.1. SetEIODll
4. Delivery
Visual Eiffel input/output (IO) performed via BASIC_IO is supported using a set of DLLs (eioc.dll, eiow.dll, eio_name.dll) plus special API to manipulate these DLLs. 'eioc.dll' is used for all console Eiffel applications, 'eiow.dll' is used for all non-console (GUI) applications and 'eio_name.dll' is used for attaching Visual Eiffel DLLs to specified input/output.
IO attaching depends whether it is performed from the executable module or from DLL. There are two corresponding sections below.
By default any executable file uses input/output depending on the project 'target': if the target is 'exe console' then eioc.dll is attached to the executable, otherwise eiow.dll is attached. There is also a possibility to set your own IO DLL.
In order to set your own DLL for IO, you have to specify in .ESD file the following project option: "io_lib <your_io_lib_name>". In this case all input/output from the executable will be redirected to DLL with name <your_io_lib_name>.
Example. Specify in .ESD file the following options 'target exe console' and 'io_lib "%VE_BIN/eiow.lib"' and recompile the project. As a result all output performed via BASIC_IO will be redirected to real GUI window, though the application remains console one.
All console-oriented input/output (STD_FILES, BASIC_IO) is not linked in the DLL generated by Visual Eiffel. Special dynamic IO resolution is used in run-time instead. So, both console and windows executables can share the same DLL and there would be no conflicts in the IO.
Before all IO activities Eiffel DLL reads the name of its IO DLL from the eio_name.dll. After that Eiffel DLL tunes all IO routine's addresses (using special API described below), and then Eiffel DLL can produce any IO actions.
If you use Eiffel executable module that is linked with Eiffel DLL then it is possible to fall into the strange situation: your executable uses your own IO (due to option "io_lib <your_io_lib_name>") but your DLL uses one of standard IO DLLs instead. Be careful: if you want to redirect IO for DLL you have to set corresponding name BEFORE all IO actions in the DLL. Otherwise the DLL would be tuned to the default IO scheme.
Visual Eiffel IO API can be divided into two parts: API to manipulate basic input/output actions such as put_string, read_char, etc. and API that is used for DLL IO attaching. To support both APIs corresponding import libraries are (automatically) linked in all applications assembled by the Visual Eiffel.
This API must be implemented in any IO DLL used by Visual Eiffel applications. Even if some feature(s) are not used in particular user application the corresponding name must be included in the DLL export. Otherwise the behaviour of the Visual Eiffel system will be unpredictable.
EIF_BOOLEAN IOAttach (HINSTANCE hInstance, HANDLE *hSupHeap, DWORD param)
Purpose
Opens IO system.
Return value
IOAttach returns True if the function succeeds. If the function fails, the return value is False.
Parameters
hInstance
Instance handle. It can be used for GUI operations.
hSupHeap
Pointer to local heap handle. You can use the handle for memory alloc operations.
param
Any parameter you want to use in your IO system. It is set by SetEIODll (see below).
void IODetach (void)
Purpose
Closes IO system.
Return value
None.
Parameters
None.
EIF_BOOLEAN _io_get_boolean (EIF_REFERENCE current, EIF_BOOLEAN *dest_bool)
Purpose
Reads a boolean from the current input.
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the input. For example, you can use CECIL to manipulate with fields of the object (maybe, to redirect input or to support several input devices).
dest_bool
Pointer to boolean value placeholder where result would be placed.
EIF_BOOLEAN _io_get_character (EIF_REFERENCE current, EIF_CHARACTER *dest_char)
Purpose
Reads a single character from the current input.
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the input.
dest_char
Pointer to character value placeholder where result would be placed.
EIF_BOOLEAN _io_get_double (EIF_REFERENCE current, EIF_DOUBLE *dest_double)
Purpose
Reads a double from the current input.
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the input.
dest_double
Pointer to double value placeholder where result would be placed.
EIF_BOOLEAN _io_get_int (EIF_REFERENCE current, EIF_INTEGER *dest_int)
Purpose
Reads an integer from the current input.
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the input.
dest_int
Pointer to integer value placeholder where result would be placed.
EIF_BOOLEAN _io_get_newline (EIF_REFERENCE current)
Purpose
Consume input until a newline is found, then consume the newline character.
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the input.
EIF_BOOLEAN _io_get_real (EIF_REFERENCE current, EIF_REAL *dest_real)
Purpose
Reads a real value from the current input.
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the input.
dest_real
Pointer to real value placeholder where result would be placed.
EIF_BOOLEAN _io_get_line (EIF_REFERENCE current, char **string, EIF_INTEGER *length)
Purpose
Reads a string from the current input.
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the input.
string
Pointer to string buffer placeholder where result string would be placed.
length
Pointer to string length placeholder where result string length would be placed.
EIF_BOOLEAN _io_put_string (EIF_REFERENCE current, char *string, EIF_INTEGER length)
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the output.
string
Pointer to output string value.
length
Length of the output string.
EIF_BOOLEAN _io_put_int (EIF_REFERENCE current, EIF_INTEGER integer)
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the output.
integer
Output integer value.
EIF_BOOLEAN _io_put_real (EIF_REFERENCE current, EIF_REAL real)
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the output.
real
Output real value.
EIF_BOOLEAN _io_put_double (EIF_REFERENCE current, EIF_DOUBLE dbl)
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the output.
dbl
Output double value.
EIF_BOOLEAN _io_put_char (EIF_REFERENCE current, EIF_INTEGER ch)
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the output.
ch
Character value for output.
EIF_BOOLEAN _io_put_boolean (EIF_REFERENCE current, EIF_BOOLEAN b)
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the output.
ch
Boolean value for output.
EIF_BOOLEAN _io_put_newline (EIF_REFERENCE current)
Return value
On success, returns True.
On error, returns False.
Parameters
current
Reference to Eiffel object which provides access to the output.
IOEXPIMP void printError (char *msg)
Return value
None.
Parameters
msg
Error message.
The API consists of one feature and implemented in eio_name.dll.
void SetEIODll (char *eioname, DWORD param);
Purpose
Links Eiffel IO system with specified DLL.
Return value
None.
Parameters
eioname
Name of the DLL used as IO system by Eiffel DLL.
param
Any parameter you want to pass to your IO system. It would be elaborated by IOAttach (described above).
Visual Eiffel supplies the following source files which may be necessary to create your own IO DLL:
The following source files are distributed as an example of Visual Eiffel IO system usage: