|
||||
The Eiffel Support PagesUsing external functions from EiffelThis note complements the basic information on calling external functions from Eiffel, as given in chapter 24 of the language reference, Eiffel: The Language For any advanced use of C with Eiffel you should also be familiar with Cecil library, for which an and the on-line presentation is also available. Eiffel and C types
When incorporating external C functions into an Eiffel system
you may rely on the macros and functions defined in
$EIFFEL4/bench/spec/$PLATFORM/include/eiffel.h
Eiffel C INTEGER EIF_INTEGER BOOLEAN EIF_BOOLEAN CHARACTER EIF_CHARACTER REAL EIF_REAL DOUBLE EIF_DOUBLE OBJECT EIF_REFERENCE PROCEDURE EIF_PROC To pass the address of an Eiffel routine to C, you must use the $ operator. The resulting type on the C side is EIF_PROC. Passing Eiffel objects to CThere are two ways to pass an Eiffel object to the C side. You must remember that the adress of an Eiffel object may change during garbage collection cycles. Therefore it is not always safe to pass the actual adress of an Eiffel object to the C side (it might not remain valid throughout the entire life of an application). By default, when you pass an Eiffel object to an external routine, you do not receive the "raw" address to the object on the C side, but a "protected" reference to the address. That reference is managed by the run-time, and updated whenever necessary. The type of the protected reference on the C side is EIF_OBJ. To access the actual object you must call the routine eif_access. Note that the Eiffel object is only protected until the end of the call to external routine. If you wish to have a permanent protection on an Eiffel object you must use the eif_adopt function (which takes an EIF_OBJ as argument and returns and EIF_OBJ). You may pass the "raw" address of an Eiffel object to C by using the $ operator, but in that case you must be sure that the object will not move in memory because of the garbage collector. Note that you cannot combine the $ operator with dot (.) notations.
Example 1External C function performing a multiplication of integers:C sideEIF_INTEGER mult (a, b) EIF_INTEGER a; EIF_INTEGER b; { return (EIF_INTEGER) ((int) a * (int) b); } Eiffel sidemult (a, b: INTEGER): INTEGER is external "C" end Example 2Calling an Eiffel routine from C:Eiffel sideclass EXAMPLE creation make feature make is do to_c (Current, $f); call_c end; f is do io.pustring ("Hello%N") end; feature -- External to_c (obj: EXAMPLE; proc: POINTER) external "C" end; call_c is external "C" end end C side#include "eiffel.h" EIF_OBJ eiffel_object; EIF_PROC eiffel_procedure; void to_c (obj, proc) EIF_OBJ obj; EIF_PROC proc; { eiffel_object = eif_adopt (obj); eiffel_procedure = proc; } void call_c () { (eiffel_procedure)(eif_access (eiffel_object)); /* Here you need to pass the Eiffel object */ }
|