1. Cannot use 'call_back' for a procedure
- Posted by ArthurCrump Aug 27, 2010
- 1319 views
I want to use call_back(routine_id("procedure_name")) but Euphoria refuses to use call_back on a procedure and insists on a function or type.
An error handler can be specified for the FreeImage library.
The error handler should be specified with a VOID result.
In Euphoria that is a procedure, not a function.
The error handler is registered to FreeImage using FreeImage_SetOutputMessage
requiring the machine address of the error handler.
Unfortunately, call_back only seems to work with functions and types.
When the error handler is specified as a procedure Euphoria reports an error.
On the other hand, if the error handler is specified as a function, the program disappears on returning from the error handler.
At present a win32lib abortErr(...) is used and shows the appropriate error message from FreeImage.
How can I get it to register a procedure as the error handler?
Arthur
2. Re: Cannot use 'call_back' for a procedure
- Posted by jimcbrown (admin) Aug 27, 2010
- 1376 views
Normally, using a function as a callback that returns 0 is OK for C code that expects a void function. Not sure why your code is behaving differently.
I made a simple wrapper, available at http://malcom.unkmar.com/lostsouls/testd.dll , that should allow you to wrap your Euphoria callback and make it appear as a true void function to the C code.
Here is the source code:
int(*void_call_back_1_func)(); int(*void_call_back_2_func)(); int(*void_call_back_3_func)(); int(*void_call_back_4_func)(); int(*void_call_back_5_func)(); void set_call_back_1(int(*f)()) { void_call_back_1_func = f; } void void_call_back_1(void) { void_call_back_1_func(); } void set_call_back_2(int(*f)()) { void_call_back_2_func = f; } void void_call_back_2(void) { void_call_back_2_func(); } void set_call_back_3(int(*f)()) { void_call_back_3_func = f; } void void_call_back_3(void) { void_call_back_3_func(); } void set_call_back_4(int(*f)()) { void_call_back_4_func = f; } void void_call_back_4(void) { void_call_back_4_func(); } void set_call_back_5(int(*f)()) { void_call_back_5_func = f; } void void_call_back_5(void) { void_call_back_5_func(); }
3. Re: Cannot use 'call_back' for a procedure
- Posted by ArthurCrump Aug 27, 2010
- 1254 views
Thank you; I will try that tomorrow.
4. Re: Cannot use 'call_back' for a procedure
- Posted by ArthurCrump Aug 28, 2010
- 1221 views
I have downloaded the testd.dll suggested by jimcbrown and thought I would be able to sort out how to use it. Unfortunately my attempt just caused a machine failure. Can I please beg for some instructions on its use?
What I want to do is to link an error handler routine to the FreeImage library.
My first attempt was simply:
c_proc(xfiSetOutputMessage,{call_back(routine_id("FreeImageErrorHandler"))})
where FreeImage ErrorHandler is my own error handler routine and xfiSetOutPutMessage is the address of FreeImage_SetOutputMessage in the FreeImage library.
My error handler works as a function up to the point where it returns to the FreeImage library. Then the program disappears.
5. Re: Cannot use 'call_back' for a procedure
- Posted by jimcbrown (admin) Aug 28, 2010
- 1285 views
I have downloaded the testd.dll suggested by jimcbrown and thought I would be able to sort out how to use it. Unfortunately my attempt just caused a machine failure. Can I please beg for some instructions on its use?
I've updated a new dll based on your response below, and it is available at http://malcom.unkmar.com/lostsouls/testfi.dll
Here is the source:
int(*void_call_back_1_func)(int x, const char * y); int(*void_call_back_2_func)(int x, const char * y); int(*void_call_back_3_func)(int x, const char * y); int(*void_call_back_4_func)(int x, const char * y); int(*void_call_back_5_func)(int x, const char * y); void set_call_back_1(int(*f)(int x, const char * y)) { void_call_back_1_func = f; } void void_call_back_1(int x, const char * y) { void_call_back_1_func(x, y); } void set_call_back_2(int(*f)(int x, const char * y)) { void_call_back_2_func = f; } void void_call_back_2(int x, const char * y) { void_call_back_2_func(x, y); } void set_call_back_3(int(*f)(int x, const char * y)) { void_call_back_3_func = f; } void void_call_back_3(int x, const char * y) { void_call_back_3_func(x, y); } void set_call_back_4(int(*f)(int x, const char * y)) { void_call_back_4_func = f; } void void_call_back_4(int x, const char * y) { void_call_back_4_func(x, y); } void set_call_back_5(int(*f)(int x, const char * y)) { void_call_back_5_func = f; } void void_call_back_5(int x, const char * y) { void_call_back_5_func(x, y); }
And here is some example code:
include std/dll.e atom testfi = open_dll("testfi.dll") atom callbackptr = define_c_var(testfi, "void_call_back_1") atom set_callback = define_c_proc(testfi, "set_call_back_1", C_POINTER) c_proc(set_callback, {call_back(routine_id("FreeImageErrorHandler"))}) c_proc(xfiSetOutputMessage,{callbackptr})
This was tricky to figure out because the first parameter of FreeImageErrorHandler is an enum, which does not have a defined bit size. (On most C compilers, it's usually the same size as an int, but this is not guaranteed.)
What I want to do is to link an error handler routine to the FreeImage library.
My first attempt was simply:
c_proc(xfiSetOutputMessage,{call_back(routine_id("FreeImageErrorHandler"))})
where FreeImage ErrorHandler is my own error handler routine and xfiSetOutPutMessage is the address of FreeImage_SetOutputMessage in the FreeImage library.
My error handler works as a function up to the point where it returns to the FreeImage library. Then the program disappears.
Other than the trickiness with enum bitsizes, there is nothing unusual or tricky about FreeImage's SetOutputMessage function or the FreeImage_OutputMessageFunction.
I wonder if you are using 3.11 and have DEP enabled. That would cause the sort of crash you are seeing, and it would occur on any time of call_back, not just void function call_backs.
6. Re: Cannot use 'call_back' for a procedure
- Posted by ArthurCrump Aug 29, 2010
- 1186 views
Thank you. I will try that.
I am using Euphoria version 4 beta 2, being too idle to install beta3.
Ideally, I would like the routine to work on version 4 and version 3, but if I can get it working on Euphoria version 4, I will be happy.
Thank you again.
Arthur
7. Re: Cannot use 'call_back' for a procedure
- Posted by ArthurCrump Aug 29, 2010
- 1142 views
I tried testfi.dll and realised, after a time, that I needed
c_proc(xfiSetOutputMessage,{peek4u(callbackptr)})
That got it into the error handler and I could show the error message, but the program still disappears when it returns to FreeImage.
I will concentrate on the rest of the routine and its documentation for now and leave the error handler until later.
Thank you for you interest in this; you have been most helpful.
Arthur
8. Re: Cannot use 'call_back' for a procedure
- Posted by ArthurCrump Aug 31, 2010
- 1072 views
Finally solved it:
I decided not to trust the FreeImage documentation which says it uses stdcall conventions. I tried cdecl conventions and the error handler returned to me! I used:
c_proc(xfiSetOutputMessage,{call_back({'+',routine_id("FreeImageErrorHandler")})})
I assume that the other calls to FreeImage must use stdcall or else nothing would work. So this must be something that the FreeImage writers let slip by.
Arthur