1. Cannot use 'call_back' for a procedure

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

new topic     » topic index » view message » categorize

2. Re: Cannot use 'call_back' for a procedure

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(); 
} 
new topic     » goto parent     » topic index » view message » categorize

3. Re: Cannot use 'call_back' for a procedure

Thank you; I will try that tomorrow.

new topic     » goto parent     » topic index » view message » categorize

4. Re: Cannot use 'call_back' for a procedure

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.

new topic     » goto parent     » topic index » view message » categorize

5. Re: Cannot use 'call_back' for a procedure

ArthurCrump said...

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.)

ArthurCrump said...

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.

new topic     » goto parent     » topic index » view message » categorize

6. Re: Cannot use 'call_back' for a procedure

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

new topic     » goto parent     » topic index » view message » categorize

7. Re: Cannot use 'call_back' for a procedure

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

new topic     » goto parent     » topic index » view message » categorize

8. Re: Cannot use 'call_back' for a procedure

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu