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));
}
After having a problem with creating a STRING from a std::string (c++): Here's the solution
cpp_get_text: STRING is -- 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 and evaluate twice its argument, so for efficiency it should be:
cpp_get_text: STRING is -- 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
What kind of configuration this example requires ?
Greetings, Simply creating the files for c++ example does not let me compile the results in Eiffel Studio. The compiler complains that it can't find application.h There are other examples which refer to header files under Eiffel Studio setup dir, but I could not figure out if there is a configuration setting that'd make compiler find header file.
So, are there any chances of getting the Eiffel Studio project dir for me, or could you please point me in the right direction to get this working?
This example seems to be related to an issue I'm wrestling with at the moment.
Kind regards Seref
The file `application.h' is specified in that post, it is one of the text boxes.
Thanks, I should have been clearer. I've used the .h file, but could not include it in Eiffel studio. Then I found out how to do it, and created a sample project using the code in this article. My problem is, Eiffel Studio can't compile this code. I get the following error:
C1/Cobj1.o:big_file_C1_cpp.cpp:(.text+0xb2b): undefined reference to `operator new(unsigned int) collect2: ld returned 1 exit status make.exe": *** [callbacktest.exe] Error 1
What I can't understand is, the header file declares a C++ class. Eiffel studio uses the C compiler, so I would not expect the C compiler to make use of a C++ header. This is the bit I'm failing to understand.
Regards Seref