Re: Wrapping Callback Functions
- Posted by ghaberek (admin) Nov 02, 2020
- 959 views
Hello all,
I need a little help. I'm wondering if this is how you wrap callback functions.
//C Code typedef void* (*NewtonAllocMemory) (int sizeInBytes); typedef void (*NewtonFreeMemory) (void* const ptr, int sizeInBytes);
No, that is not at all correct. These are typedefs which name a new type. In this case, that type is the signature of each call back function. They're call backs which means they're addresses of functions where the library calls you. (Insert Yakov Smirnoff joke here.)
Call back functions by their nature should not exist in the library you're calling. The docs for NewtonAlocMemory even state: This is not a library function, but a callback event. So you need to define your call back functions to match the signatures as provided. In Euphoria, that means each parameter must be an atom.
Then the library should have a way to set those call back addresses so it can call your function when the time comes. In this case it looks like that's NewtonSetMemorySystem. Which, by the way, states it is not neccesary to call this function at all in the documentation, so in this particular case all of this work may be moot (unless you want to set up custom memory allocation).
Edit: since we've determined this uses cdecl on 32-bit Windows, we also need to preface our call backs with '+' to force cdecl inside Euphoria.
-- -- This is the library function to set the call backs. -- constant xNewtonSetMemorySystem = define_c_proc( newton "NewtonSetMemorySystem", {C_POINTER,C_POINTER} ) -- void NewtonSetMemorySystem (NewtonAllocMemory malloc, NewtonFreeMemory free) public procedure NewtonSetMemorySystem( atom malloc_func, atom free_func ) c_proc( xNewtonSetMemorySystem, {malloc_func,free_func} ) end procedure -- -- This is our implementation of the alloc function. -- -- typedef void* (*NewtonAllocMemory) (int sizeInBytes); function NewtonAllocMemory( atom sizeInBytes ) return allocate( sizeInBytes ) end function constant NewtonAllocMemory_id = routine_id( "NewtonAllocMemory" ) constant NewtonAllocMemory_cb = call_back({ '+', NewtonAllocMemory_id }) -- -- This is our implementation of the free function. -- -- typedef void (*NewtonFreeMemory) (void* const ptr, int sizeInBytes) function NewtonFreeMemory( atom ptr, atom sizeInBytes ) free( ptr ) return NULL end function constant NewtonFreeMemory_id = routine_id( "NewtonFreeMemory" ) constant NewtonFreeMemory_cb = call_back({ '+', NewtonFreeMemory_id }) -- -- Call the library function to set the call back addresses. -- NewtonSetMemorySystem( NewtonAllocMemory_cb, NewtonFreeMemory_cb )
-Greg