ePolyglot: Examination and development of multilanguage programming using Eiffel, Python, and Haskell | ||
---|---|---|
Prev | Chapter 11. Calling Eiffel from Python | Next |
The second step, generating the C files and the cecil-generated header file, can be accommodated by a fairly simple make target. But what about the third step--exposing the generated stubs to SWIG through an interface file?
The information we need shouldn't be difficult to get. We've already decided what functionality to export by including it in the cecil.se file, so typing everything in by hand again is unnecessary duplication of effort. In fact, all that we really need is located in the bottom of the automatically-generated eiffel-glue.h file, and that's where we can look for it. Since SmallEiffel generates the same stub code for all automatically-generated files, then appends the exported functions to the end, it's relatively easy for us to go straight to that file, search for the comments marking the available Eiffel routines exported via CECIL, and copy everything past that into a new interface file, which is exactly what the simple Python script make_eiffel_glue_i.py does. Consider an eiffel class CALLED_FROM_PYTHON which is exporting the features print_message (which prints a simple message) and print_integer_addition (which prints the result of adding two integers together). Since the cecil.se file is automatically generated by SWIG, we add a couple of lines to it to create the cecil_final.se file below:
Example 11-4. The cecil_final.se file, showing our newly-exported functions
-- The name of the include C file : eiffel-glue.h -- The features you want to call from C : string_from_external STRING from_external string_to_external STRING to_external character_array_to_external ARRAY[CHARACTER] to_external integer_array_to_external ARRAY[INTEGER] to_external real_array_to_external ARRAY[REAL] to_external double_array_to_external ARRAY[DOUBLE] to_external test_print_message CALLED_FROM_PYTHON print_message test_print_integer_addition CALLED_FROM_PYTHON print_integer_addition |
To simplify this, the new exported features are kept in a cecil_additions.se file and added to the cecil.se file to produce cecil_final.se through the use of a make target. The compile_to_c program is run to generate the eiffel-glue.h header file, and the make_eiffel_glue_i.py script is then run on the generated header file to produce the eiffel-glue.i file:
Example 11-5. The automatically-generated eiffel-glue.i file
//This module file generated by the make_eiffel_glue_i.py script %module eiffel_glue %{ #include "eiffel-glue.h" %} extern void initialize_eiffel_runtime( int argc, char** argv); extern void* eiffel_root_object; void test_print_integer_addition(void* C,int a1,int a2); void test_print_message(void* C); void* double_array_to_external(void* C); void* real_array_to_external(void* C); void* integer_array_to_external(void* C); void* character_array_to_external(void* C); void* string_to_external(void* C); void string_from_external(void* C,void* a1); |
With all that done, SWIG is then run on the generated eiffel-glue.i file to create the wrapper code for the functions, in the form of the eiffel-glue_wrap.c source code file and the eiffel-glue_wrap.doc file containing brief documentation for the exported commands.