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
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
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));
}
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
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
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));
}
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));
}



After having a problem with
After having a problem with creating a STRING from a std::string (c++): Here's the solution
-- Get some dummy text
external
"C++ inline use <string>"
alias
"[
std::string a = "dummy";
return RTMS(((char*)a.c_str()));
"]
end
Note that RTMS is a macro
Note that RTMS is a macro and evaluate twice its argument, so for efficiency it should be:
-- Get some dummy text
external
"C++ inline use <string>"
alias
"[
std::string a = "dummy";
char *c_str = (char*) a.c_str();
return RTMS(c_str);
"]
end