i have made a sample example, in this i'm trying to pass a function as argument i am getting error, could you please help me
typedef void (*callbackptr)(int,int);
class Myfirst
{
public:
Myfirst();
~Myfirst();
void add(int i,callbackptr ptr)
{
ptr(i,3);
}
};
class Mysec
{
public:
Myfirst first_ptr;
Mysec();
~Mysec();
void TestCallback()
{
callbackptr pass_ptr = NULL;
pass_ptr = &Mysec::Testing;
first_ptr.add(2,&Mysec::Testing);
}
void Testing(int a,int b)
{
int c = a+b;
}
};
The type of the callback function you're passing as parameter is not defined as part of a class. You probably should define Testing as static.
You are geting an error because you are pointing to a member function. Pointers to member functions are different. See here:
http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.1
A member function needs to know what instance it is working with (the this pointer) so it can't be called like any other function. If you moved the callback function out of the class (or made it static, which is similar to moving it out of the class) you could call it like any other function.
A more modern way of doing this is to use functors, e.g. boost::function and something like boost::bind :
C++ Functors - and their uses
how boost::function and boost::bind work
Those can hide the difference between member and global functions.
You are trying to access a member function pointer here, using a simple function pointer typedef, which will not work. Let me explain.
When you write a normal, non-member function (similar to C), the function's code actually exists in a location indicated by the name of the function - which you would pass to a function pointer parameter.
However, in the case of a member function, all you have is the class definition; you don't have the actual instance of the class allocated in memory yet. In such a function, since the this pointer is not yet defined, any reference to member variables wouldn't make sense, since the compiler doesn't have enough information to resolve their memory locations. In fact, member function pointers are not exact addresses; they encode more information than that (which may not be visible to you). For more, read Pointers to Member Functions.
Related
So I got myself onto shaky ground by insisting on making a C++ class immitate a regular function. The class overloads the function operator, making it a functor, of course. This all works fine, until you want to pass the function pointer of this functor.
Naturally, I want to let the compiler know that we know what we're doing (lol), by doing a reinterpret_cast of this pointer. However, how do I get the address of this particular member function, since it is an overloaded operator. How does one get the address of that?
UPDATE: You asked for an example. Here is a minimal one.
So I have an interface, which I cannot change. It looks like this;
typedef void (*some_callback_t)(SomeType);'
void someFunc(some_callback_t);
Now, this is quite straight-forward; the API is setting some callback function pointer. So, the idea was to implement the callback as a functor class, by overloading the operator(), like so, as usual.
class Bah {
void operator()(SomeType);
};
Here comes the question; seeing as I cannot change the API used (the function that expects a function pointer of a certain signature), how can I then get the address of the member function and pass that?
I suspect it goes something like;
someFunc(reinterpet_cast<some_callback_t>( ? ? ? )); to make sure that the compiler won't barf at me.
Supposing that you have to use a function pointer, and that your functor has no state, you can use a lambda as glue:
void takesFunctionPointer(void (*)());
struct MyFunctor {
void operator()();
};
// ...
takesFunctionPointer([] { return MyFunctor{}(); });
How does one get the address of that?
In the same way as any other member function. The name of the function is class_name::operator(). An example:
struct class_name {
void operator()(){}
};
void (class_name::*member_function_pointer)() = &class_name::operator();
class_name instance;
(instance.*member_function_pointer)(); // in a block scope
Naturally, I want to let the compiler know that we know what we're doing (lol), by doing a reinterpret_cast of this pointer.
That's usually not what one would want to do.
I'm trying to implement more flexibility in my numerics by allowing me to choose different forms of a mathematical function and vary their parameters through instantiating them as objects of a certain class. That class includes certain mathematical functions I may choose plus parameters that I can vary. The constructor of the class sets a member function pointer in the class to a member function according to what mathematical function I want. I want to solely use the pointer to call whatever function it points to by directly using the pointer in my routine.
However, that proved daunting as I didn't know that member function pointers require a certain syntax and seem to work somewhat differently from regular function pointers according to what I could gather. I've experimented quite a bit and constructed myself a minimal example shared below.
#include<iostream>
#include<string.h>
#include<cstdlib>
#include<stdio.h>
class Someclass
{
public:
// constructor to set pointer
Someclass(std::string);
// member function pointer to hold functions
void (Someclass::*fptr)();
// auxiliary function to call testfunction via pointer
void call ();
// testfunction
void foo();
};
// testfunction
void Someclass::foo()
{
printf("foo says hi! \n");
}
// call via specific function
void Someclass::call()
{
(this->*fptr)();
}
// constructor
Someclass::Someclass(std::string name)
{
if(name=="foo")
{
this->fptr = &Someclass::foo;
}
}
int main()
{
Someclass someobject("foo");
someobject.foo(); // direct testfunction call: Works OK
someobject.call(); // call via auxiliary function: Works OK
//(someobject.*fptr)(); // direct pointer dereferencing: Gives Error
return(EXIT_SUCCESS);
}
It shows that I can access the pointer by use of another member function that just calls whatever the pointer points to via use of a this pointer. However, I still can't seem to get the function call to work if I try to use the pointer directly in my main function through the line,
(someobject.*fptr)()
This particular expression leads to my compiler complaining about the scope and if I include the class scope, the compiler mentions invalid use of non-static members. Still, I'm confused as to why my implementation here doesn't work and if it does, how the proper syntax in my problem would be and why that has to be so.
Any insights would be really appreciated.
fptr is a member of the object, not a variable local to main. In such respect member function pointers behave exactly the same as all other variable types. You were so close, and just need to qualify the function pointer name with the object name:
(someobject.*(someobject.fptr))();
The reasons for this is .* indicates a pointer to member function and does not directly reference the members of an object like the . and .-> operators. Since fptr is a member of Someclass and not a local variable you need to reference it directly like so
(someobject.*someobject.fptr)();
Sorry to ask such a question as I'm sure it's been answered before, but I'm struggling to find an answer and it's not for the want of looking... anyway..
class foo
{
void read(void (*func)(obj&))
{
// many things happen to obj...
(*func)(obj); // Calls the function pointer to the handler.
}
};
class bar : public foo
{
void handler(obj&)
{
//
}
};
void main()
{
foo f;
typedef void (foo::*funcptr)(obj&);
funcptr ptr = &foo::handler;
f.read(ptr); ????
}
So basically, all I'm trying to do is pass the non-static member method called handler as a function pointer to the read method, so that when the callback is executed, the handler is called.
I've tried all sorts of ways to make this work and don't want to make static methods (for reasons I won't go into). I think I'm pretty close, but have sort of fallen over right at the end! Any help would be appreciated.
You cannot do that: unlike static functions that can be called on their own, the call of a member function requires knowledge of two things - the function being called, and the object on which to call it. That is why it is not possible to pass a member function to an API expecting a "plain" function pointer.
If you do not have access to the source of the foo class, you can create a static function that calls a member function on an object stored at a well-known location (i.e. in a static variable). If you do, consider changing the API to take a function object, similar to what functions from the standard C++ library do.
Finally, there is a common approach used in C libraries that take function pointers - passing an additional void* pointer, which will be passed back in a call to your function pointer; pthreads library does that. If this is the case, you can create a struct that wraps the invocation target object, and pass a pointer to this struct to be passed back to your static function.
AFAIK I don't think there is any other way. You will have to make the method static.
This is probably something elementary, I have a function from one class (called cell) with identifier woo_func_ptr taking a pointer to function of type void with no arguments (void (*void_ptr)(void)) (which I typedef). In another class, I have an object of cell and I use the method woo_func_ptr. It won't allow me to, I get the error in the above title. If these two functions were not embedded inside a class, they would work fine
typedef void (*void_ptr)(void);
double WOO{0};
struct cell {
void woo_func_ptr(void_ptr jo)
{
jo();
}
};
class woosah
{
public:
void woo_func()
{
WOO+=rand();
std::cout << WOO << std::endl;
};
void run()
{
// other stuff
temp_cell.woo_func_ptr(woo_func);
// yet more stuff
}
cell temp_cell;
};
First of all pointer to woosah member function should be declared as
typedef void (woosah::*void_ptr)(void);
and then compiler would complain that it needs to see woosah definition while parsing this statement.
If you let compiler parse class woosah first by moving it up then it will complain that type cell is not defined (since it is contained within woosah). That wil still not solve your problem because of cyclic dependency while parsing.
One way is to solve cyclic dependency is by making temp_cell a pointer to cell instance and have it contained within woosah.
Also note, the syntax to call member function is by using .* or ->*
void run()
{
// other stuff
temp_cell->woo_func_ptr(temp_cell->*woo_func); // assuming temp_cell is pointer to some cell instance
// yet more stuff
}
http://msdn.microsoft.com/en-us/library/b0x1aatf(v=vs.80).aspx shows similar errors and their fixes.
A member function is not like a regular function. That's why there's a seperate "pointer to member function" type. It's because member functions are passed the implicit this pointer.
In fact, the standard even limits (severly) the casting of pointer to member function.
That's the source of your error.
You could use a static class function...
Change
void woo_func()
to
static void woo_func()
This will of coarse may not be what you want if you are trying to access data members of a particular object.
Member functions are kind of special and should not be treated as normal functions.
What's the best way to call a member function if you have an object and a bare function pointer pointing to the member? Essentially I want to call the function pointer with thiscall calling convention.
Background: I'm looking up symbols in a shared library dynamically, obtaining a factory function pointer and a pointer to a certain member function I want to call. The member function itself is not virtual. I have no control over the shared library, I just have the binary.
Example:
typedef void * (*GenericFptr)();
GenericFptr lookup(const char *);
class CFoo;
GenericFptr factoryfn(lookup("CFoo factory function"));
CFoo *foo = reinterpret_cast<CFoo *>(factoryfn());
GenericFptr memberfn(lookup("CFoo member function"));
// now invoke memberfn on foo
Currently I'm using an union to convert the function pointer to a pointer to member function. It's ugly and creates dependencies to compiler implementation details:
class CFoo {
public:
void *dummy() { return 0; }
};
typedef void * (CFoo::*FooMemberPtr)();
union {
struct {
// compiler-specific layout for pointer-to-member
void *x, *y;
GenericFptr ptr;
} fnptr;
FooMemberPtr memberfn;
} f;
f.memberfn = &CFoo::dummy; // init pointer-to-member
f.fnptr.ptr = memberfn; // rewrite pointer
void *result = (foo->*f.memberfn)();
A pointer to member function can't be stored in a pointer to function because it needs more information (for instance in case of multiple inheritance an offset may have to be applied to this before the call). So you can't do without knowledge of implementation details.
If you want to be portable, the easiest is for your library to provide wrapper functions doing the member call.
Unfortunately a member function pointer has more information than a standard function pointer, and when you get the standard function pointer, converting it to a member function pointer would effectively be trying to generate extra data out of thin air.
I don't think there's any portable way to do what you're attempting, although if the union appears to work you could probably get away with that. Again, you would need to know the representation and calling convention for these methods for each compiler you wish to use to build the bode.
If you know the member function's name, why can't you just do foo->dummy() for example? Otherwise either the lookup function needs to provide a full member function pointer or the library would have to provided a C wrapper interface with normal functions to which a this pointer can be passed.
The following two links provide insight and possibly a solution. Note that calling a member function pointer with a this argument usually don't work, since you must take into account virtual methods, multiple and virtual inheritance.
http://www.codeproject.com/KB/cpp/FastDelegate.aspx
http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx
According to the answer below it is doable in GCC, but not portable:
https://stackoverflow.com/a/5067992/705086