I have a problem handling a function pointer.I have made a class Control that has a function pointer as member:
void (*mouseFunction) (Control*, Event*);
The member is protected, and it has setter and getter:
void (*getMouseFunction()) (Control*,Event*)
{
return mouseFunction;
}
void setMouseFunction( void (*mouseFunction) (Control*, Event*) )
{
this->mouseFunction=mouseFunction;
}
The problem is that even after setting the pointer, it's always NULL.
I have a function declared inside a header file:
void mouseFunction (Control* control, Event* event)
{
std::cout << "Inside Text Field";
}
If I try to assign it:
myControlInstance.setMouseFunction(mouseFunction);
If I use the getter to get the pointer it's NULL; and if I try to execute the function I get EXC_BAD_ACCESS:
error: address doesn't contain a section that points to a section in a object file
Following cod is working, so be sure that youre method is public to be accessible from other place than object.
typedef int Event;
class Control
{
public:
void (*mouseFunction) (Control*, Event*);
void (*getMouseFunction()) (Control*,Event*)
{
return mouseFunction;
}
void setMouseFunction( void (*mouseFunction) (Control*, Event*) )
{
this->mouseFunction=mouseFunction;
}
};
void mouseFunction (Control* control, Event* event)
{
printf ("test");
}
int _tmain(int argc, _TCHAR* argv[])
{
Control c;
c.setMouseFunction(mouseFunction);
Event e = 1;
c.mouseFunction(&c,&e);
return 0;
}
Your problem might be with inlining. Since the function is declared and defined at the same point, and inside a header.. the compiler may be treating it as an implicit inline (please note that it is up to the compiler to decide whether or not to actually inline it). If the function is inlined, then the compiler would have to jump through some extra hoops to make it possible to store a pointer to that function (i.e., the compiler would have to have a non-inline version of the function built). If the compiler doesn't make this happen, then you're going to have problems storing and calling a function pointer to the function.
To eliminate this as a possible source of the problem, try moving the function's implementation out into a cpp file, which is one common way to prevent implicit inlining (and usually better style anyway).
Related
I'm trying to make a table of function pointers within a class. I haven't been able to find any examples of this online, most involve using member function pointers outside of their class.
for example:
class Test
{
typedef void (Test::*FunctionType)();
FunctionType table[0x100];
void TestFunc()
{
}
void FillTable()
{
for(int i = 0; i < 0x100; i++)
table[i] = &Test::TestFunc;
}
void Execute(int which)
{
table[which]();
}
}test;
Gives me the error "term does not evaluate to a function taking 0 arguments".
In this line in the Execute function:
table[which]();
You can't call it like that because it's not a normal function. You have to provide it with an object on which to operate, because it's a pointer to a member function, not a pointer to a function (there's a difference):
(this->*table[which])();
That will make the invoking object whichever object is pointed to by the this pointer (the one that's executing Execute).
Also, when posting errors, make sure to include the line on which the error occurs.
Seth has the right answer. Next time, look up the compiler error number on MSDN and you'll see the same: Compiler Error C2064.
You need a context in which to call your function. In your case, the context is this:
void Execute(int which)
{
(this->*table[which])();
}
I'm trying to create a struct that have 2 function, which may be rewritten if needed later. The functions are: onClicked() and onClickedRight(). The code for the struct:
typedef struct {
QString text;
QString infoText;
QUrl iconSrc;
QColor iconColor;
void (*onClicked)() = nullptr;
void (*(*onClickedRight))() = &onClicked; // by default, execute the same function from onClicked()
} ConfigButton;
How I'm trying to execute these functions:
ConfigButton b;
...
// test if click funtion has been defined, to execute it
if (b.onClicked)
b.onClicked(); // this one work just fine
...
if (*(b.onClickedRight))
(*(b.onClickedRight))(); // this one crashed
Is it even possible? Am I missing something?
When onClicked is a function, both &onClicked and onClicked evaluate to the same thing -- a pointer to the function.
If you want to create a pointer to a function pointer, you need a pointer to a function as a variable first.
However, given your usage, you need just a pointer to a function.
typedef struct {
QString text;
QString infoText;
QUrl iconSrc;
QColor iconColor;
void (*onClicked)() = nullptr;
void (*onClickedRight)() = onClicked;
} ConfigButton;
and
if ( b.onClickedRight)
b.onClickedRight();
I think you can still solve your issue with a pointer to a function pointer, yet it is a bit clumsy, since you have to call this pointer-pointer in a different manner than you do with a "normal" function pointer. The call would look like (*(aButton.onRightClick))(), and you need to let onRightClick point to a pointer object pointing to a function rather than assigning the function directly.
I suppose you are looking for a way to define that onRightClick shall by default "inherit" the behaviour of onClick, unless the user overrides this and assigns a different behaviour to onRightClick. I see two requirements that a possible solution shall fulfill:
1) If onRightClick did not get overridden, it shall inherit every change made to onClick
2) If onRightClick gets overridden, it gets decoupled from onClick.
You can solve this with "simple" function pointers by assigning onRightClick a function that simply calls the one assigned to onClick. The following code shows this for C++; the approach can be transferred to C (though you then need to pass the "this" to the function calling onClick:
void defaultOnClick() {
std::cout << "defaultOnClick" << std::endl;
}
void otherClick() {
std::cout << "otherClick" << std::endl;
}
void rightClick() {
std::cout << "rightClick" << std::endl;
}
typedef std::function<void(void)> onClickFunctionType;
struct ConfigButton {
onClickFunctionType onClick = defaultOnClick;
onClickFunctionType onRightClick = [this](){ this->onClick(); };
} ;
int main() {
ConfigButton configButton;
std::cout << "default for both onClick and onRightClick (calling onClick)" << std::endl;
configButton.onClick();
configButton.onRightClick();
std::cout << "special click for onClick; 'inherited' by onRightClick" << std::endl;
configButton.onClick = otherClick;
configButton.onClick();
configButton.onRightClick();
std::cout << "special click for onClick; different one for onRightClick" << std::endl;
configButton.onRightClick = rightClick;
configButton.onClick();
configButton.onRightClick();
}
Output:
default for both onClick and onRightClick (calling onClick)
defaultOnClick
defaultOnClick
special click for onClick; 'inherited' by onRightClick
otherClick
otherClick
special click for onClick; different one for onRightClick
otherClick
rightClick
Answer adjusted, since OP has removed c from the tag list.
The code works as is. So you are doing something else wrong.
However, using a pointer to a pointer to a function in this way may not have the semantics that you want. If the structure gets copied to another structure, the onClickedRight member in the copy is not pointing to the onClicked pointer in its own instance. It is instead pointing to the onClicked pointer of the original instance.
a.onClickedRight = &a.onClicked;
b = a;
assert(b.onClickedRight == &a.onClicked); // Is this intentional?
What this means is that you have to be extra careful about how you use structures that contain pointers to its own members (and pointers to anything, really). You will probably need some kind of deep copy method (so, according to TRoT, you need a copy constructor, an assignment operator, and a destructor).
In any case, the C++ code is not really idiomatic. For myself, I would probably leverage virtual methods. The virtual method syntax can easily accommodate this use case.
struct ConfigButton {
QString text;
QString infoText;
QUrl iconSrc;
QColor iconColor;
virtual void onClicked() const = 0;
virtual void onClickedRight () const { onClicked(); }
};
struct Foo : ConfigButton {
void onClicked () const {
//...
}
};
If you follow this method, this will also work.
One possible approach is to have functions that implement the logic of firing the handler. You already have some logic (if (onClicked)) that the caller has to do anyway, so this minimizes the possibility of the caller making a mistake .
struct ConfigButton {
// ...
void Fire_OnClicked()
{
if ( onClicked )
onClicked();
}
void Fire_OnClickedRight()
{
if ( onClickedRight )
onClickedRight();
else
Fire_OnClicked();
}
private:
void (*onClicked)() = nullptr;
void (*onClickedRight)() = nullptr;
};
You could combine this with the std::function version, testing for empty instead of requiring "empty" to be represented by a lambda performing the default action. And if there are multiple handlers you want to have default fallback you could reduce boilerplate by making a template Fire function.
Another approach that might work would be to make a custom handler type with similar semantics to std::function but its () operator will perform a default action if no function has been set .
In the C language functions pointers are the only place where hiding pointers behind typedefs makes sense
https://godbolt.org/z/Gb_WEy
#include <stdio.h>
typedef int (*fptr_t)();
typedef struct
{
fptr_t fptr;
fptr_t *pfptr;
fptr_t **ppfptr;
fptr_t ***pppfptr;
}MYSTRUCT_t;
int foo(char *caller)
{
printf("Function name = %s, caller = %s\n", __FUNCTION__, caller);
return 0;
}
int main()
{
MYSTRUCT_t mystr;
mystr.fptr = foo;
mystr.pfptr = &mystr.fptr;
mystr.ppfptr = &mystr.pfptr;
mystr.pppfptr = &mystr.ppfptr;
printf("mystr.fptr=%p mystr.pfptr=%p func=%p\n", (void *)mystr.fptr, (void *)mystr.pfptr, (void *)&foo);
foo("foo");
mystr.fptr("mystr.fptr");
(*mystr.pfptr)("mystr.pfptr");
(*(*mystr.ppfptr))("mystr.ppfptr");
(*(*(*mystr.pppfptr)))("mystr.pppfptr");
}
Suppose that I have this code:
class MyClass
{
public:
void SomeFunction()
{
// Find somehow if this is first, second, or third call of a function in a main loop
// If the function is called first time create new variables that will be used just for this function call
}
};
MyClass myClassObject;
int main()
{
myClassObject.SomeFunction(); // First call
myClassObject.SomeFunction(); // Second call
myClassObject.SomeFunction(); // Third call
}
How can I know inside function what number of call is it?
Note that I will probably have 100 function calls placed in code. Also this should work in Visual Studio on Windows and Clang on Mac.
I had one workaround:
void SomeFunction(const char* indetifier = "address")
{
CheckAddress(indetifier); // This will check if address is stored. If it is not, create variables, if it is, if addresses matches use variables that are tied to that address.
}
I tried not to assign a new string to an "indetifier" and to let it to use default string ("address"). This of course didn't worked well as compiler will optimize "indetifier", so I was thinking that maybe a solution would be to disable optimizations for that variable, but I didn't because there should be some more elegant solution.
Also one thing came on my mind, maybe I could force inline a function and then get it's address, but this also seams like bad workaround.
I could also create new classes for every call but I would like to avoid this as there will be a lot of function calls and I don't want to think 100 different names.
If there is a way to create class object only at first call this would be awesome.
I hope that you understand what I want, sorry if something is not that clear as I am beginner coder.. :D
EDIT:
I can't use static for variables in a class because software that I am developing is a plugin that could have multiple instances loaded inside host and this will probably mess up the variables. I have tested static variables and if I create for example "static int value" anywhere and write something in it in one instance of a plugin this "value" will be updated for all instances of a plugin and this is not something that I want.
void SomeFunction()
{
// Find somehow if this is first, second, or third call of a function in a main loop
// If the function is called first time create new variables that will be used just for this function call
}
If the first call is to be tracked per object, then you need a member variable that keeps track of how many times SomeFuntion has been called for that object.
If the first call is to be tracked independent of objects, then you can use a static function variable that keeps track of how many times SomeFuntion has been called for that object.
I can't use static for variables in a class because software that I am developing is a plugin that could have multiple instances loaded inside host and this will probably mess up the variables. I have tested static variables and if I create for example "static int value" anywhere and write something in it in one instance of a plugin this "value" will be updated for all instances of a plugin and this is not something that I want.
So make a non-static counter?
class MyClass {
int count;
public:
MyClass () : count(0) { }
void SomeFunction () {
++ count;
// do stuff with 'count'
}
};
MyClass myClassObject;
int main () {
myClassObject.SomeFunction(); // First call
myClassObject.SomeFunction(); // Second call
myClassObject.SomeFunction(); // Third call
}
Or just pass it as a parameter...
class MyClass {
public:
void SomeFunction (int count) {
// do stuff with 'count'
}
};
MyClass myClassObject;
int main () {
myClassObject.SomeFunction(1); // First call
myClassObject.SomeFunction(2); // Second call
myClassObject.SomeFunction(3); // Third call
}
But I'm really wondering what you're actually trying to do, and I highly suggest sitting back and rethinking this whole thing, because there are a number of red flags / confusing points here...
If you're only interested in checking whether it's the first call, you can add a bool SomeFunction_first_call; to the MyClass, to act as a flag. The constructor sets the bool to true. MyClass::SomeFunction() uses the conditional check if (SomeFunction_first_call) /* ... */ to determine whether it's the first call, as follows:
class MyClass
{
bool SomeFunction_first_call;
public:
MyClass() : SomeFunction_first_call(true) {}
void SomeFunction()
{
if (SomeFunction_first_call)
{
// This code only executes on first call.
do_something();
// Successfully handled first call, set flag to false.
SomeFunction_first_call = false;
}
// This code always executes.
do_something();
}
};
Similarly, if you're only concerned about the first HOWEVER_MANY_CALLS calls, where HOWEVER_MANY_CALLS is a number, you can use something like this:
#include <cstdint>
class MyClass
{
uint8_t SomeFunction_calls;
public:
MyClass() : SomeFunction_calls(0) {}
void SomeFunction()
{
// This segment will be executed until (SomeFunction_calls == HOWEVER_MANY_CALLS).
// After this, the segment will be skipped, and the counter will no longer increment.
if (SomeFunction_calls < HOWEVER_MANY_CALLS)
{
// This code only executes on first HOWEVER_MANY_CALLS calls.
do_something();
// Increment counter.
++SomeFunction_calls;
}
// This code always executes.
do_something();
}
};
Make sure to use the appropriately signed variable for the number of calls that need special handling (i.e. uint8_t for 0..255, uint16_t for 256..65,535, etc.). If different instances of MyClass will need to keep track of a different number of calls, then use a non-type template parameter to indicate this, and optionally, a defaulted typename to indicate what type the counter should be.
#include <cstdint>
template<uint64_t N, typename T = uint64_t>
class MyClass {
T SomeFunction_calls;
...
void SomeFunction()
{
if (SomeFunction_calls < N) {
...
}
...
}
};
In this case, a MyClass<4> will have special treatment for the first 4 calls to SomeFunction(), a MyClass<4444444444444444444> will have special treatment for the first 4,444,444,444,444,444,444 calls, and so on. The counter will default to uint64_t, as that should be large enough to hold the value; when only a smaller number of calls need special treatment, you can specify a smaller type, such as MyClass<4, uint8_t> or MyClass<444444444, uint32_t>.
In C++ you can use the static keyword in a local variable context to create the object only once at the first call:
#include <iostream>
struct MyObject {
MyObject() {
std::cout << "Creating instance " << this << "\n";
};
};
void foo() {
static MyObject my_instance;
std::cout << "... inside function foo ...\n";
}
int main(int argc, const char *argv[]) {
std::cout << "About to call foo...\n";
foo();
std::cout << "... second call ...\n";
foo();
std::cout << "... third call ...\n";
foo();
return 0;
}
With the above code you will notice that only on object MyObject will be created, on the first call to foo.
Note that if your function is a template then for each instantiation of the template you will get another distinct static variable. For example with:
template<int N>
void foo() {
static MyObject my_instance;
std::cout << "... inside function foo ...\n";
}
the all the calls to foo<1>() will use the same variable but calling instead foo<2>() will access another copy of the function (another instantiation of the function template), that will have its own distinct static variable created on the first call to foo<2>(). All static variables that have been initialized will be destroyed after the end of main when the program terminates.
I am creating a wrapper class that wraps a bunch of functions outlined in a particular 3rd party API. When I try to wrap non-member functions like this:
(AVTcamDllWrapper.h)
typedef VmbErrorType (WINAPI * AVTGETCAMERAS) (CameraPtrVector cameras);
class CAVTcamDllWrapper
{
HMODULE mAVTCamLibrary; //I later have this point to the DLL
public:
void AVTGetCameras (CameraPtrVector cameras);
};
(AVTcamDllWrapper.cpp)
void CAVTcamDllWrapper::AVTGetCameras(AVTNS CameraPtrVector cameras)
{
AVTGETCAMERAS pFunc = NULL;
pFunc = (AVTGETCAMERAS) GetProcAddress(mAVTCamLibrary, "?GetCameras#VimbaSystem#VmbAPI#AVT##AEAA?AW4VmbErrorType##PEAV?$shared_ptr#VCamera#VmbAPI#AVT###23#AEAI#Z");
DWORD dw = GetLastError();
if(pFunc == NULL)
{
Exlog(L"CAVTcamDllWrapper::AVTGetCameras: Failed to locate AVTGetCameras method in AVTCamera DLL.");
NIERR_SET_AND_THROW_ERROR(NIERR_CAMERA_ERROR, L"Failed to locate AVTGetCameras method in AVTCamera DLL.");
}
VmbErrorType vErr = pFunc(cameras);
if(vErr != VmbErrorSuccess)
{
wstring exLogMsg = Format(exLogMsg, L"CAVTcamDllWrapper::AVTGetCameras(): Failed to get any cameras. VmbErrorType = %d", vErr);
Exlog(exLogMsg.c_str());
NIERR_SET_AND_THROW_ERROR(NIERR_CAMERA_ERROR, L"Failed to get any cameras.");
}
}
The above code works great for non-member functions. For example, if I am trying to wrap a function that is called simply by saying:
CallFunction(blah, blaaaaah);
then the wrapper class works fine, and the pFunc is set properly and no error occurs on the VmbErrorType vErr = pFunc(); line;
However, many of my functions are member function, and are called like this:
SomeObject.CallMemberFunction(blah, bleh);
// or
SomeObjectPointer->CallMemberFunction(what, ever);
and these are the functions I can't seem to wrap. The error occurs on the line:
VmbErrorType vErr = pFunc();
because the function cannot be called without a specific object to call it from. In my example, I am wrapping a function GetCameras which exists inside of Camera. Without wrapping the function, to call it I simply create a vector of Camera pointers, and do:
cameras[0]->GetCameras(VmbAccessModeFull);
which works. But I have no idea how I would go about wrapping this function, as the call to GetCameras is both dependent on cameras[0] and completely useless without a camera to call it from.
So how do I wrap member functions like the one shown above?
Edit 1:
I have tried to pass in a reference to a specific object and do
VmbErrorType vErr = theObject->pFunc();
but obviously this won't work because then it will think to look for a function named pFunc inside of theObject, which doesn't exist.
Edit 2:
I feel like I would almost have modify the wrapper function to pass the reference object in as a parameter or something. So like instead of the regular:
cameras[0]->GetCameras(VmbAccessModeFull);
I would have to modify some stuff and make my wrapper function look like this:
mWrapperObject->WrappedGetCameras(VmbAccessModeFull, cameras[0]);
so that the wrapped function will have the context it needs to act as a member function.
To call a member function you must have an object at hand. To have an object you must get it from somewhere. The only place a good little well-behaving function can get stuff from is its parameter list.
So each of your functions obviously must have a parameter that receives The Object.
If you want your wrapper functions to be callable from C, you cannot have class types as function parameters. So you either declare it as a void* and do a cast inside, or just cheat and type it (for C only!) struct YourClassName* (without ever defining the struct). For C++, it should still use the class keyword. Use the preprocessor.
In a nutshell,
foo->bar(moo, roo)
is the fancy shmancy C++ way of saying
FooType_bar(foo, moo, roo)
and you should think about wrapping the latter while actually spelling the former.
How the caller obtains The Object then? One of your functions could create objects (with new) and return pointers to them. Another one could do a delete. Or you can return pointers to elements of a pre-allocated array. Or whatever. Basically you wrap the ways you use to obtain pointers to objects as a user of the original, unwrapped library.
That's about it.
You just need to pass the this pointer as first argument if you are calling memberfunctions and make sure you are using the right calling convention. For static member functions you don´t have to pass the this pointer.
On x64 you would not even have to worry about calling conventions, as everything will be compiled as __fastcall. No matter what calling convention you specify.
#include <iostream>
#include <stdint.h>
class Camera
{
int i;
public:
Camera()
{
i = 123;
}
void __stdcall print_1(int j, int k)
{
std::cout << i << j << k << std::endl;
}
void __cdecl print_2(int j, int k)
{
std::cout << i << j << k << std::endl;
}
void print_3(int j, int k)
{
std::cout << i << j << k << std::endl;
}
static void __cdecl print_s1(int j, int k)
{
std::cout << j << k << std::endl;
}
static void __stdcall print_s2(int j, int k)
{
std::cout << j << k << std::endl;
}
};
int main() {
Camera cam;
Camera* pCam = &cam;
// call __stdcall memberfunction
typedef void (__stdcall* tprint_1)(Camera*,int,int);
tprint_1 print_1 = (tprint_1)&Camera::print_1;
print_1(pCam,1,2);
// call __cdecl memberfunction
typedef void (__cdecl* tprint_2)(Camera*,int,int);
tprint_2 print_2 = (tprint_2)&Camera::print_2;
print_2(pCam,3,4);
// call __thiscall memberfunction
typedef void (__thiscall* tprint_3)(Camera*,int,int);
tprint_3 print_3 = (tprint_3)&Camera::print_3;
print_3(pCam,5,6);
// call __thiscall memberfunction different syntax
typedef void (Camera::* tprint_4)(int,int);
tprint_4 print_4 = (tprint_4)&Camera::print_3;
(pCam->*print_4)(7,8);
// static member functions don´t take a this pointer
typedef void(__cdecl* tprint_s1)(int,int);
tprint_s1 print_s1 = (tprint_s1)&Camera::print_s1;
print_s1(9,10);
// static member functions don´t take a this pointer
typedef void(__stdcall* tprint_s2)(int,int);
tprint_s2 print_s2 = (tprint_s2)&Camera::print_s2;
print_s2(11,12);
return 0;
}
You can do this by converthing the thiscall for memberfunctions to a fastcall
http://www.unknowncheats.me/forum/c-and-c/73849-thiscall-hooking.html
Here's how it's done. Say you have two layers: The member function layer and the wrapper function layer. What you need to do is create a third layer that lies in between these two layers, and export this layer to a .dll file. At first (back when I asked the question) I was trying to wrap functions that looked like this:
void SomeClass::SomeFunction(CString someParam)
{
//blah blah
}
This didn't work because, as the question describes, you cannot wrap member functions. What I discovered was that I needed to do all of the object management on a layer above the member function calls, but still below the wrapper functions. What I ended up with was a bunch of "Bridge" functions (that's what I called them) that "bridge" the gap between the wrapper functions and the member functions. So now, I wrapped functions that looked like this:
void BridgedSomeFunction(CString someParam)
{
classObject.SomeFunction(someParam);
}
Then I simply did some __declspec(dllexport)'s and __declspec(dllimport)'s to turn these functions into a .dll file, and that's it!
Think of your basic GLUT programs. They simply run from a main method and contain callbacks like `glutMouseFunc(MouseButton) where MouseButton is the name of a method.
What I have done is I have encapsulated the main file into a class, so that MouseButton is no longer a static function but has an instance. But doing this gives me a compilation error :
Error 2 error C3867: 'StartHand::MouseButton': function call missing argument list; use '&StartHand::MouseButton' to create a pointer to member c:\users\angeleyes\documents\visual studio 2008\projects\capstone ver 4\starthand.cpp 388 IK Engine
It is not possible to provide a code sample as the class is quite huge.
I have tried using this->MouseButton but that gives the same error. Can't a pointer to an instance function be given for callback?
As the error message says, you must use &StartHand::MouseButton syntax to get a pointer to a member function (ptmf); this is simply mandated as part of the language.
When using a ptmf, the function you are calling, glutMouseFunc in this case, must also expect to get a ptmf as a callback, otherwise using your non-static MouseButton won't work. Instead, a common technique is for callbacks to work with a user-supplied void* context, which can be the instance pointer—but the library doing the callbacks must explicitly allow this parameter. It's also important to make sure you match the ABI expected by the external library (the handle_mouse function below).
Since glut doesn't allow user-supplied context, you have to use another mechanism: associate your objects with glut's current window. It does provide a way to get the "current window", however, and I've used this to associate a void* with the window. Then you simply need to create a trampoline to do the type conversion and call the method.
Machinery:
#include <map>
int glutGetWindow() { return 0; } // make this example compile and run ##E##
typedef std::pair<void*, void (*)(void*,int,int,int,int)> MouseCallback;
typedef std::map<int, MouseCallback> MouseCallbacks;
MouseCallbacks mouse_callbacks;
extern "C" void handle_mouse(int button, int state, int x, int y) {
MouseCallbacks::iterator i = mouse_callbacks.find(glutGetWindow());
if (i != mouse_callbacks.end()) { // should always be true, but possibly not
// if deregistering and events arrive
i->second.second(i->second.first, button, state, x, y);
}
}
void set_mousefunc(
MouseCallback::first_type obj,
MouseCallback::second_type f
) {
assert(obj); // preconditions
assert(f);
mouse_callbacks[glutGetWindow()] = MouseCallback(obj, f);
//glutMouseFunc(handle_mouse); // uncomment in non-example ##E##
handle_mouse(0, 0, 0, 0); // pretend it's triggered immediately ##E##
}
void unset_mousefunc() {
MouseCallbacks::iterator i = mouse_callbacks.find(glutGetWindow());
if (i != mouse_callbacks.end()) {
mouse_callbacks.erase(i);
//glutMouseFunc(0); // uncomment in non-example ##E##
}
}
Example:
#include <iostream>
struct Example {
void MouseButton(int button, int state, int x, int y) {
std::cout << "callback\n";
}
static void MouseButtonCallback(
void* self, int button, int state, int x, int y
) {
static_cast<Example*>(self)->MouseButton(button, state, x, y);
}
};
int main() {
Example obj;
set_mousefunc(&obj, &Example::MouseButtonCallback);
return 0;
}
Notice that you don't call glutMouseFunc directly anymore; it is managed as part of [un]set_mousefunc.
Just in case it isn't clear: I've rewritten this answer so it should work for you and so that it avoids the C/C++ linkage issue being debated. It will compile and run as-is (without glut), and it should work with glut with only minor modification: comment or uncomment the 4 lines marked ##E##.
No, a pointer to an instance function can not be given to a callback function expecting a function pointer of a certain signature. Their signatures are different. It won't compile.
Generally such APIs allow you to pass in a void* as a "context" parameter. You pass in your object there, and write a wrapper function which takes the context as the callback. The wrapper casts it back to whatever class you were using, and calls the appropriate member function.
You can't replace a static callback with an instance one. When the caller calls your callback, on what instance whoul it call? In other words, how does the caller pass in the formal 'this' argument?
The solution is to have a static callback stub and pass the instance as argument, which implies the callee must accept an arbitrary pvoid that will pass back when invoking the callback. In the stub, you can then call the non-static method:
class C {
void f() {...}
static void F(void* p) {
C* pC = (C*)p;
pC->f();
}
}
C* pC = ...;
someComponent.setCallback(&C::F, pC);
Contrary to what everyone seems to be saying, you most definitely CAN use a non-static member function as a callback method. It requires special syntax designed specifically for getting pointers to non-static members, and special syntax to call that function on a specific instance of a class. See here for a discussion of the needed syntax.
Here is sample code that illustrates how this works:
#include <cstdlib>
#include <string>
#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;
class Operational
{
public:
Operational(int value) : value_(value) {};
string FormatValue() const ;
private:
int value_;
};
string Operational::FormatValue() const
{
stringstream ss;
ss << "My value is " << value_;
return ss.str();
}
typedef string(Operational::*FormatFn)() const; // note the funky syntax
Operational make_oper(int val)
{
return Operational(val);
}
int main()
{
// build the list of objects with the instance callbacks we want to call
Operational ops[] = {1, 2, 3, 5, 8, 13};
size_t numOps = sizeof(ops)/sizeof(ops[0]);
// now call the instance callbacks
for( size_t i = 0; i < numOps; ++i )
{
// get the function pointer
FormatFn fn = &Operational::FormatValue;
// get a pointer to the instance
Operational* op = &ops[i];
// call the callback on the instance
string retval = (op->*fn)();
// display the output
cout << "The object # " << hex << (void*)op << " said: '" << retval << "'" << endl;
}
return 0;
}
The output of this program when I ran it on my machine was:
The object # 0017F938 said: 'My value is 1'
The object # 0017F93C said: 'My value is 2'
The object # 0017F940 said: 'My value is 3'
The object # 0017F944 said: 'My value is 5'
The object # 0017F948 said: 'My value is 8'
The object # 0017F94C said: 'My value is 13'
You cannot use a non-static member function in this case.
Basically the type of the argument expected by glutMouseFunc is
void (*)(int, int, int, int)
while the type of your non-static member function is
void (StartHand::*)(int, int, int, int)
First problem is that types don't really match.
Second, in order to be able to call that method, the callback would have to know which object ( i.e. "this" pointer ) your method belongs to ( that's pretty much why the types are different in the first place ).
And third, I think you're using the wrong syntax to retrieve the method's pointer. The right syntax should be: &StartHand::MouseButton.
So, you have to either make that method static or use some other static method that would know which StartHand pointer to use to call MouseButton.
The following works in c++ to define a c callback function, useful for example when using glut (glutDisplayFunc, glutKeyboardFunc, glutMouseFunc ...) when you only need a single instance of this class :
MyClass * ptr_global_instance = NULL;
extern "C" void mouse_buttons_callback(int button, int state, int x, int y) {
// c function call which calls your c++ class method
ptr_global_instance->mouse_buttons_cb(button, state, x, y);
}
void MyClass::mouse_buttons_cb(int button, int state, int x, int y) {
// this is actual body of callback - ie. if (button == GLUT_LEFT_BUTTON) ...
// implemented as a c++ method
}
void MyClass::setup_glut(int argc, char** argv) { // largely boilerplate glut setup
glutInit(&argc, argv);
// ... the usual suspects go here like glutInitWindowSize(900, 800); ...
setupMouseButtonCallback(); // <-- custom linkage of c++ to cb
// ... other glut setup calls here
}
void MyClass::setupMouseButtonCallback() {
// c++ method which registers c function callback
::ptr_global_instance = this;
::glutMouseFunc(::mouse_buttons_callback);
}
In your MyClass header we add :
void mouse_buttons_cb(int button, int state, int x, int y);
void setupMouseButtonCallback();
This also works using identical logic flows to setup your glut
call to glutDisplayFunc(display)