- Category: Example
- Level: Intermediate
Most existing examples on how to do external calls contain a lot of English explanation which can distract people, like myself, who learn by example. This is intended to be a compilable, terse example of how to call in and out of C/C++.
This is a C example:
class APPLICATION create make feature -- Initialization make is -- Run application. do create callback c_set_routine (callback.routine) c_set_object ($callback) c_do_callback end callback: CALLABLE feature{NONE} c_set_routine (routine: POINTER) is external "C inline use %"application.h%"" alias "c_set_routine ($routine);" end c_set_object (obj: POINTER) is external "C inline use %"application.h%"" alias "c_set_object ($obj);" end c_do_callback is external "C inline use %"application.h%"" alias "c_do_callback();" end end -- class APPLICATION
class CALLABLE feature inside is local current_addr: POINTER do current_addr := $Current io.put_string ("We're inside at address: " + current_addr.to_integer_32.out) io.put_new_line end routine: POINTER is do result := $inside end end
application.h:
#include "eif_eiffel.h" EIF_OBJECT obj = NULL; EIF_POINTER routine; void c_set_routine (EIF_POINTER routine_a) { routine = routine_a; } void c_set_object (EIF_REFERENCE obj_a) { if(obj != NULL) { eif_wean (obj); } obj = eif_protect (obj_a); } void c_do_callback () { ((void (*) (EIF_REFERENCE)) routine) (eif_access (obj)); }
This is a similar C++ example:
class APPLICATION create make feature -- Initialization make is do create call cpp_obj := c_new c_set_routine (cpp_obj, call.routine) c_set_object (cpp_obj, $call) c_do_callback (cpp_obj) end cpp_obj: POINTER call: CALLABLE feature {NONE} c_new: POINTER is external "C++ inline use %"application.h%"" alias "[ return new test_class; ]" end c_set_routine (obj: POINTER routine: POINTER) is external "C++ inline use %"application.h%"" alias "((test_class *) ($obj))->c_set_routine ($routine);" end c_set_object (obj: POINTER e_obj: POINTER) is external "C++ inline use %"application.h%"" alias "((test_class *) ($obj))->c_set_object ((EIF_REFERENCE)$e_obj);" end c_do_callback (obj: POINTER) is external "C++ inline use %"application.h%"" alias "((test_class *) ($obj))->c_do_callback();" end end
class CALLABLE feature inside is local current_addr: POINTER do current_addr := $Current io.put_string ("We're inside at address: " + current_addr.to_integer_32.out) io.put_new_line end routine: POINTER is do result := $inside end end
application.h:
#include "eif_eiffel.h" class test_class { public: test_class(); ~test_class(); EIF_OBJECT obj; EIF_POINTER routine; void c_set_object (EIF_REFERENCE obj_a); void c_set_routine (EIF_POINTER routine_a); void c_do_callback (); }; test_class::test_class() { } void test_class::c_set_object (EIF_REFERENCE obj_a) { if (obj != NULL) { eif_wean (obj); } obj = eif_protect (obj_a); } void test_class::c_set_routine (EIF_POINTER routine_a) { routine = routine_a; } void test_class::c_do_callback () { ((void (*) (EIF_REFERENCE)) routine) (eif_access (obj)); }

Comments
After having a problem with
After having a problem with creating a STRING from a std::string (c++): Here's the solution
Note that RTMS is a macro
Note that RTMS is a macro and evaluate twice its argument, so for efficiency it should be: