This section describes calling conventions used by the Visual Eiffel compiler for DLLs.
1. Specifying DLL target
2. Exporting features from DLL
2.1. Selecting Eiffel features to be exported
2.2. Linking application with DLL
3. Initializing DLL module
3.1. Eiffel routines called to initialize DLL
3.2. Restrictions to the creation routine of root
class
3.3. Input/Output
4. Calling DLL routines
4.1. Naming convention
4.2. Calling DLL routines from Eiffel
4.3. Calling DLL routines from C
4.4. Types of parameters passed to DLL routines and function
results
5. Run-time requirements
Visual Eiffel compiler can generate both executable and DLL modules. The type of the generated module depends on value specified in the "target" option in Eiffel System Description. Setting this option to "EXE" would result in generating executable module and setting this option to "DLL" - DLL module.
In order to use DLL, features to be called from the executable or another DLL are to be selected. These features are said to be exported. Visual Eiffel compiler automatically exports all generally available (i.e. exported to ANY) features of root class. No other features can be exported.
If Visual Eiffel generates DLL it also generates export library with the same name and ".imp" extension. In order to invoke Eiffel routines from the DLL the application using this DLL can be linked with corresponding export library.
Before an application which uses DLL starts, the operating system initializes DLL. At the stage of DLL initialization Visual Eiffel run-time calls the creation routine of the root class mentioned in Eiffel System Description. Note, that this creation routine is called before the client application starts.
At the moment when the creation routine of the root class is called the corresponding application is not started yet. Therefore there is no associated console or window for this application. Hence the creation routine of the root class should not call any routines which perform any input or output.
If the creation routine of the root class has a parameter which reflects the program arguments in ARRAY [STRING] then it gets Void value because DLL does not have any command line arguments.
All console-oriented input/output (produced with BASIC_IO) is not linked in the DLL generated by Visual Eiffel. Special dynamic I/O resolution is used in run-time instead. Actual routines to perform all this I/O are taken from the executable which invokes the DLL. So, both console and windows executables can share the same DLL and there would be no conflicts in the I/O.
This mechanism is supported by the special Visual Eiffel conventions and API. The main rule sounds as follows: the input/output of the DLL coincides with the input/output of executable. This rule is applicable in the case when the executable is produced by Visual Eiffel. Otherwise DLL is attached to the console input/output.
Visual Eiffel automatically supplies external names for all exported routines. The name of the exported routine in the object module coincides with a name of the Eiffel routine prepended by an underscore. This is standard naming convention for programs written in C.
Example.
Suppose the root class of the DLL module contains the feature with the following interface
foo (i : INTEGER; flag : BOOLEAN) : REAL;
Then it would get name "_foo" in the object module.
As mentioned above the routines from the DLL behave as usual C routines. Therefore in Eiffel they are to be described as external routines.
Example.
Application in Eiffel which uses the routine from the previous example should have the corresponding routine which is described as follows:
call_foo (i : INTEGER; flag : BOOLEAN) : REAL is external "C" alias "foo" end -- call_foo
Note, that "C" (but not "CWC") external calling convention is used because the routine being called corresponds to the root class, so the run-time itself performs the proper substitution of the Current object.
Eiffel routines may be called from the C code as if they were usual external C routines. No special calling convention should be specified in the routine declaration.
Example.
An application in C which calls the same Eiffel routine as in the previous example should contain the following declaration and call statements:
extern REAL foo (INTEGER i, BOOLEAN flag); REAL x; ... x = foo (125, TRUE); ...
An application and DLL run in the same address space. However, they are different systems. For example, if both of them are written in Eiffel, the application has one set of classes and corresponding objects, while the DLL has another set. Visual Eiffel uses a special convention for the object structure which reflects some object properties. It is not legal to mix objects created in different Eiffel systems. Therefore the only types which may be used to interchange between the application and the DLL are basic types. They are listed below:
Only these types may be used for parameters of DLL routines and their results.
Run-time requires that if the program uses Eiffel DLLs then only one component of it may be built with run-time in DLL option turned on. It means that if the executable is built with run-time in DLL then no DLL can be built with the same option turned on. If one of DLLs is built with this option turned on then all other components (i.e. executable and other DLLs) should be built with this option turned off.
In the current version this is enforced by disabling "run-time in DLL" option for DLLs.