Why should I use the static method for using this callback? - c++

I'm trying to implement Marmalade's IwBilling (c++) but all is what I get is the error: "Reference to non-static member function must be called".
I use the following code:
=== [ main cpp file ] ===
#include <s3e.h>
#include "MyGame.h"
int main () {
IwGxInit();
{
MyGame game = new MyGame();
}
IwGxTerminate();
}
=== [ MyGame.h ] ===
#include "IwBilling.h"
class MyGame{
void billingError( void* caller, IwBilling::CIwBillingErrorData* data ) {}
MyGame() {
if ( IwBilling::isAvailable() && IwBilling::Init() ) {
IwBilling::setErrorCallback( billingError ); // !!! ERROR: Reference to non-static member function must be called
}
}
};
What's the problem here? Why do this works like this? If I write: "static void billingError" all works fine. But I don't know if that correct to use static before void billingError?
I don't understand why my MyGame() constructor is a static method? How can I do it non-static?

In C++, nonstatic member functions are always associated with an instance of the class that they are declared within. Thus in order to call them, you have to have an instance of that class available. So if billingError() is declared nonstatic, you would have to call it with an instance of MyGame like this:
MyGame* myGame = new MyGame();
myGame->billingError(); // myGame is the instance for this call
Static functions can be called without an instance of the class like so:
MyGame::billingError(); // assuming billingError() was declared static
The reason for this distinction is nonstatic member functions have an implicit 'this' pointer passed to them, which is a pointer to the instance that the function is called on (myGame in the first example would be the 'this' pointer inside of that function). The 'this' pointer is passed as an invisible parameter to the function. Static functions on the other hand don't have any extra implicit parameters.
Because the two types of functions have different calling conventions, pointers to them are treated differently. So if you wanted to use a nonstatic billingError() function, you would have to declare setErrorCallback() to take a nonstatic function pointer and pass an instance of MyGame. For example:
class IwBilling {
void setErrorCallback( void (MyGame::*callback) (void* caller, IwBilling::CIwBillingErrorData* data), MyGame* instance ) {
// do some stuff
instance->callback(caller, data);
}
}
On the other hand, if you don't need an instance of myGame, then you can declare billingError() static, and declare the setErrorCallback() callback parameter as a static function pointer like this:
class IwBilling {
void setErrorCallback( void (*callback) (void* caller, IwBilling::CIwBillingErrorData* data) ) {
// do some stuff
callback(caller, data);
}
}

Unfortunately, IwBilling callbacks do not follow the usual pattern of passing along a user-defined void* which you could use to indicate which instance of your class to invoke the method upon. So you are probably stuck with some static ugliness like this:
class MyGame{
static MyGame* instance; // define and initialize this in your .cpp file
void billingError( void* caller, IwBilling::CIwBillingErrorData* data ) {}
static void billingErrorStatic( void* caller, IwBilling::CIwBillingErrorData* data ) {
instance->billingError(caller, data); // call the non-static method
}
MyGame() {
if ( IwBilling::isAvailable() && IwBilling::Init() ) {
IwBilling::setErrorCallback( &MyGame::billingErrorStatic );
}
}
};

Related

How to insert member function in vector? Getting Compilation error [duplicate]

I'm using C++ (not C++11). I need to make a pointer to a function inside a class. I try to do following:
void MyClass::buttonClickedEvent( int buttonId ) {
// I need to have an access to all members of MyClass's class
}
void MyClass::setEvent() {
void ( *func ) ( int );
func = buttonClickedEvent; // <-- Reference to non static member function must be called
}
setEvent();
But there's an error: "Reference to non static member function must be called". What should I do to make a pointer to a member of MyClass?
The problem is that buttonClickedEvent is a member function and you need a pointer to member in order to invoke it.
Try this:
void (MyClass::*func)(int);
func = &MyClass::buttonClickedEvent;
And then when you invoke it, you need an object of type MyClass to do so, for example this:
(this->*func)(<argument>);
http://www.codeguru.com/cpp/cpp/article.php/c17401/C-Tutorial-PointertoMember-Function.htm
You may want to have a look at https://isocpp.org/wiki/faq/pointers-to-members#fnptr-vs-memfnptr-types, especially [33.1] Is the type of "pointer-to-member-function" different from "pointer-to-function"?
you only need to add parentheses after the function call and pass arguments if needed

Setting up callback to C function pointer via non-static function in C++

A C header of interest (some_external_library.h) declares the following struct, containing a function pointer:
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
void (*function_ptr)(void);
} fp_test;
/* ... */
#ifdef __cplusplus
}
#endif
When some interesting event happens in some_external_library.c, this function pointer gets called.
I would like to set up a pointer to an instance of this struct in an instance of a C++ class called Foo, and then set the value of function_ptr to the address of a non-static function with the instance of Foo. In other words, I want my C++ code to define what this function pointer does.
For instance, here is a class declaration (foo.h):
class Foo {
public:
fp_test *fp_test_ptr;
void setup(void);
void breakdown(void);
void my_callback(void);
};
There are three functions: a setup function to initialize values, a breakdown function to release any pointers or objects, and a simple my_callback function, which takes and returns no arguments.
Here is the class definition (foo.cpp):
int main(int argc, char** argv) {
Foo some_foo;
some_foo.setup();
some_foo.breakdown();
return EXIT_SUCCESS;
}
void Foo::setup(void) {
fp_test_ptr = new fp_test;
fp_test_ptr->function_ptr = &Foo::my_callback;
}
void Foo::breakdown(void) {
delete fp_test_ptr;
}
void Foo::my_callback(void) {
std::fprintf(stderr, "Callback called...\n");
}
When I compile this, I get the following error:
foo.h:: error: assigning to 'void (*)()' from incompatible type 'void (Foo::*)()'
fp_test_ptr->function_ptr = &Foo::my_callback;
^------------------
I tried casting this call, but I get an error message indicating that I cannot cast from type void (Foo::*)() to void (*)().
How might I set up a non-static method in C++ to be a function pointer to a C library?
I was able to get a static version of Foo::my_callback() to compile, but I don't think I can use a static method for my needs, as I will not have access to the states of non-global members in the class instance some_foo, only the values of global members.
Is there a way to do this with a non-static function?
The normal way around this is to have two one functions: one static and one member function and to pass the object instance as a parameter
class Foo {
public:
fp_test *fp_test_ptr;
void setup();
void breakdown();
void my_callback();
static void _my_callback(void* self);
};
void Foo::_my_callback(void* self)
{
reinterpret_cast<Foo*>(self)->my_callback();
}
Change the C signature of the function pointer to
void (*function_ptr)(void*)
When you call it, pass the object instance as the parameter.
Edit:
To call from C, presumably you need to know which object it refers to so somehow, you need a method of passing the C++ instance to C.
Foo* fu1 = new Foo();
Foo* fu2 = new Foo();
/* fu1 and fu2 need to be passed to the C program */
...
/* Setting up */
fp_test pointerTest;
pointerTest.function_ptr = Foo::_my_callback;
...
/* Calling */
pointerTest.function_ptr(fu1);
pointerTest.function_ptr(fu2);
It is not possible. Every non-static c++ member function has a hidden "this *" parameter. So the function signature will always be different.

Reference to non-static member function must be called

I'm using C++ (not C++11). I need to make a pointer to a function inside a class. I try to do following:
void MyClass::buttonClickedEvent( int buttonId ) {
// I need to have an access to all members of MyClass's class
}
void MyClass::setEvent() {
void ( *func ) ( int );
func = buttonClickedEvent; // <-- Reference to non static member function must be called
}
setEvent();
But there's an error: "Reference to non static member function must be called". What should I do to make a pointer to a member of MyClass?
The problem is that buttonClickedEvent is a member function and you need a pointer to member in order to invoke it.
Try this:
void (MyClass::*func)(int);
func = &MyClass::buttonClickedEvent;
And then when you invoke it, you need an object of type MyClass to do so, for example this:
(this->*func)(<argument>);
http://www.codeguru.com/cpp/cpp/article.php/c17401/C-Tutorial-PointertoMember-Function.htm
You may want to have a look at https://isocpp.org/wiki/faq/pointers-to-members#fnptr-vs-memfnptr-types, especially [33.1] Is the type of "pointer-to-member-function" different from "pointer-to-function"?
you only need to add parentheses after the function call and pass arguments if needed

Is there a way to pass a member function to pthread_cleanup_push?

I want to know the way to pass a member function to pthread_clean_push. I don't want to declare the cleanup function as static and pass object's reference to it. Below is the scenario
class Foo{
public:
Foo(string name):name(name){};
void setBar1(){bar1=malloc(4);sleep(20);};
void setBar2(){bar2=malloc(10);sleep(50);};
void cleanBar1(void* arg){free(bar1);};
void cleanBar2(void* arg){free(bar2);};
private:
string name;
void* bar1;
void* bar2;
};
void* myPThread(void* arg){
Foo theFoo(*(string*)(arg));
theFoo.setBar1();
pthread_cleanup_push(&theFoo.cleanBar1,NULL); //what is the correct way to
theFoo.setBar2();
pthread_cleanup_push(&theFoo.cleanBar2,NULL); //pass clean functions?
sleep(100);
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
return NULL;
}
int main(){
string biryani="biryani";
string pappu="pappu";
pthread_t makeBirayani, makePappu;
pthread_create(&makeBiryani,NULL,&myPThread,(void*)&biryani);
pthread_create(&makePappu,NULL,&myPThread,(void*)&pappu);
pthread_join(makeBiryani,NULL);
pthread_join(makePappu,NULL);
return 0;
}
I avoided compile-time error ISO C++ forbids taking the address of a bound member function to form a pointer to member function by using (void(*)(void*))&Foo::cleanBar1 as the argument to pthread_cleanup_push(). But run-time error(segmentation fault) occurs with multiple threads as it has ambiguity in determining the instance to which the cleanup function belongs. How to invoke the member function like here in this scenario? What is the syntax?
Foo::cleanBar1 and Foo::cleanBar2 are non-static member functions, which means that they take an implicit first argument, a pointer to the Foo instance on which they must be invoked (the this pointer). So you cannot pass a pointer to member function to pthread_cleanup_push and get the desired behavior.
You'll need to create a dispatcher function that calls the member function you want, and then pass a pointer to that function to pthread_cleanup_push. This dispatch function could either be a free function, or a static member function of Foo. For instance,
class Foo{
public:
Foo(string name):name(name){}
void setBar1(){bar1=malloc(4);sleep(20);}
void cleanBar1(){free(bar1);}
static void bar1_callback(void *arg)
{
static_cast<Foo*>(arg)->cleanBar1();
}
// ..
private:
string name;
void* bar1;
void* bar2;
};
And then pass it to pthread_cleanup_push as
pthread_cleanup_push(&Foo::bar1_callback, &theFoo);
Now the call to pthread_cleanup_pop will execute Foo::bar1_callback and pass it a pointer to the theFoo instance, which will then invoke the cleanBar1() member function.
The member function needs to know the object for which it is executed. This is why the standard doesn't allow this direct reference.
Just use a lambda-wrapper, like:
pthread_cleanup_push( [](void*a)->void { reinterpret_cast<Foo*>(a)->cleanBar1(NULL);},
&theFoo); //&theFoo will be passed as argument to the function
However you MUST ensure that your theFoo object still exist when the cleanup is called, because you give its adress when you push the cleanup function, and this address will later be used as argument for the cleanup by the lambda function.
From my understanding of the pthread function pthread_cleanup_push function you can pass the address of a free function (or possibly static to the class Foo) to it and a pointer to an object and then route the call to the correct member.
void clean_bar_1(void* arg)
{
Foo* p = static_cast<Foo*>(arg);
p->cleanBar1();
}
And then in myPThread function:
pthread_cleanup_push(&clean_bar_1, &theFoo);
And repeat for the cleanBar2 method.

c++ error: invalid use of member 'calls_object::OBJECT' in static member function

I got the following error from the code below.
error: invalid use of member 'calls_object::OBJECT' in static member function|
error: from this location
from the line OBJECT->call(); line 29.
Basically the function must be static because its really a simplified version of the code
which creates a windows thread. I just can't seem to use pointers within a static function but I can create the object within the static function no problem. Is there another way?
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)windowsthread, (LPVOID)i, NULL, &m_id);
static DWORD_PTR WINAPI windowsthread()
{
OBJECT->call();
}
l
class object
{
private:
public:
object(){}
~object(){}
void call(){}
};
class calls_object
{
private:
object* OBJECT;
public:
calls_object()
{
OBJECT = new object();
}
~calls_object(){}
#ifdef _WIN32
static void windows_function()
{
OBJECT->call();
}
#endif
};
int main()
{
calls_object O;
}
This function:
static void windows_function()
{
OBJECT->call();
}
Is declared as static. It means it does not receive an implicit this pointers: in other words, it does not operate on an instance of calls_object. Therefore, it cannot see the OBJECT member variable.
Either declare the function as non-static, or declare OBJECT as a static member variable (whatever makes more sense in your application).
Basically the function must be static because its really a simplified version of the code which creates a windows thread
Since you are (unfortunately) dealing with a function (CreateThread) that accepts a function pointer, you cannot even use std::bind. However, CreateThread lets you provide a function which accepts a pointer (to void, see the prototype of ThreadProc).
Just pass a pointer to an object as the fourth argument to CreateThread, and let windowsFunction(void*) receive that pointer. Inside windowsFunction(), which would still be static or global (in fact, you do not need the calls_object class at all), you can cast that pointer to a pointer to object and invoke call() on it.
Also notice, that your class calls_object is leaking memory, since you are forgetting to delete the pointer you created in calls_object's constructor:
~calls_object()
{
delete object; // DON'T FORGET THIS!
}
windows_function is a static member function, so is not associated with any calls_object object. OBJECT is a non-static data member, so is associated with a calls_object object. You cannot access a non-static data member from a data member.
Simply make the function non-static and it will work.
Think of it this way. If you didn't even create an object of type calls_object and your main function was just:
int main()
{
calls_object::windows_function();
}
Where would you expect this function to get OBJECT from? Since OBJECT is a non-static member, it only exists as part of a calls_object object. A static member function cannot simply pull OBJECT from nowhere.