Moving Callbacks to other Code Units

edited August 2012 in Help request
This is semi-related to my old post from:
https://forum.orx-project.org/discussion/2633#Comment_2656

But in this one, I want to be able to move my callback functions to another file and still be able to hook up my clocks to them.

I have put together the following:

main.cpp
#include "orx.h"
#include "inputcontroller.h"

InputController* inputController;

orxSTATUS orxFASTCALL Init()
{
orxCLOCK *coreClock = orxClock_FindFirst(orx2F(-1.0f), orxCLOCK_TYPE_CORE);
orxClock_Register(coreClock, inputController->InputCallback, orxNULL, orxMODULE_ID_MAIN, orxCLOCK_PRIORITY_NORMAL); <--- compile error is here.
...




inputcontroller.h
#ifndef INPUTCONTROLLER_H
#define INPUTCONTROLLER_H

#include "orx.h"

class InputController {

public:

	InputController();
	void orxFASTCALL InputCallback(const orxCLOCK_INFO *_pstClockInfo, void *_pstContext);

};

#endif




inputcontroller.cpp
#include "inputcontroller.h"

InputController::InputController(){
}

void orxFASTCALL InputController::InputCallback(const orxCLOCK_INFO *_pstClockInfo, void *_pstContext){
}




Again, I realise that this is more a c++ language thing, but the special orx callback format confuses me. I assume that somehow the callback function needs to be given an extern keyword, but my experiments all failed.

Can anyone please lend me hand here?

Comments

  • edited August 2012
    Just managed to solve it in one way by making the member function (the callback) a static, ie:

    inputcontroller.h
    #ifndef INPUTCONTROLLER_H
    #define INPUTCONTROLLER_H
    
    #include "orx.h"
    
    class InputController {
    
    public:
    
    InputController();
    static void orxFASTCALL InputCallback(const orxCLOCK_INFO *_pstClockInfo, void *_pstContext);
    
    };
    
    #endif
    

    Makes sense I suppose and I'll really only be using one input controller, so I probably should make the whole class static anyway.
  • edited August 2012
    Well you already solved your problem, but here's some details: in your first attempt, you're trying to register a C++ method where a C function is expected.
    A C++ method doesn't use the same calling convention as a function (in our case, orxFASTCALL will translate in most of the cases to a fastcall calling convention whereas a C++ method has a thiscall calling convention).
    The fundamental different is that a method (thiscall) will actually send the class instance as a hidden first parameter, and the list of parameter won't match what orx is expecting on the other hand, so even if you were forcecasting the registration (yes, there's a way to do that), it'd result to undefined behavior at runtime as when orx expects a pointer to a orxCLOCK_INFO, it would get a point to your InputController instance, etc...

    When you make your declaration "static", it's no more an instance method, it becomes the equivalent of a plain old function.

    That's the exact same thing that happens in the C++ tutorial when we using static class methods for Init, Run and Exit.

    Hope this makes some sense, let me know if it's unclear. :)
  • edited August 2012
    Thanks for that, Iarwain, that definitely makes good sense.
Sign In or Register to comment.