Sign in to follow this  

C++ pointer to a function

This topic is 3412 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I successfully created a pointer to a function and executed the code using C. When I try to convert the same code into C++ it is causing trouble in making a pointer to a function. Code:
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS     5

class abc{
public:
abc();
int firstFunction();
void *PrintHello(void *threadid);
};


int main (int argc, char *argv[])
{
	abc a = abc();
	a.firstFunction();
}

abc::abc(){

}

int abc::firstFunction(){
   pthread_t threads[NUM_THREADS];
   int rc, t;
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: creating thread %d\n", t);

      // Following is the problematic line. The third argument is supposed to be   
      // a pointer to a function. When I compile the code it gives the following
      // error:
      // 1>.\main.cpp(75) : error C3867: 'abc::PrintHello': function call missing argument list; use '&abc::PrintHello' to create a pointer to member
      // When I tried to convert it into &abc::PrintHello, the compiler still 
      // complains about:
      // 'pthread_create' : cannot convert parameter 3 from 'void *(__thiscall abc::* )(void *)' to 'void *(__cdecl *)(void *)'

      rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         return 0;
      }
   }
   pthread_exit(NULL);
}

void *abc::PrintHello(void *threadid)
{
   int tid;
   tid = (int)threadid;
   printf("Hello World! It's me, thread #%d!\n", tid);
   pthread_exit(NULL);
   return NULL;
}


Any help on creating a function pointer in C++ best

Share this post


Link to post
Share on other sites
You're missing static in the declaration of your PrintHello function.

The reason is, pointers to non-static member functions are not the same as pointers to free or static member functions. Non-static member functions have one extra hidden parameter, called this, which points to the instance on which the function was called -- non-member and static member functions don't have the this parameter (and so they can't access non-static member variables, unless you give them an object to work with yourself).

In your example, you can simply make the PrintHello function static, as you don't access any member variables anyway. But that kind of defeats the point of having the function inside a class. So in more real-world situation you'll probably want to do something like
class Foo {
int id_;
void do_print_id() { std::cout << id_ << '\n'; }
public:
explicit Foo(int id) : id_(id) { }
static void print_id(void* instance) { static_cast<Foo*>(instance)->do_print_id(); }
};

...

Foo f(42);
pthread_create(..., &Foo::print_id, static_cast<void*>(&f));

Share this post


Link to post
Share on other sites
Thanks for replies :)

I did try to get help from google before posting a message here but I was not very successful. I am creating a pointer to a function from another function, and both the functions belong to the same class (refer to my code snippet).

This is what I am not able to find on the web. All the examples that I came across on the google were making a pointer to a function from outside the class, which works but does not solve my issue.

Anyway, I will try the suggestions of Oxyd

best

Share this post


Link to post
Share on other sites
What compiler do you use?

From appearances, you couldn't have compiled that same program you post in C, because you use classes, and that's impossible for a C compiler to compile, unless some strange quick fix from the compiler is supported, to include some C++ with the C.

cdecl is a C exclusive DLL, so that means, the compiler is trying to convert from the abc method(which is pure C++) to a simple C function pointer.

I don't know if it actually has to be:

abc::PrintHello

instead of:

&abc::PrintHello

The latter seems nonsensical, when you want the function address, you avoid the parenthesis, so the address operator seems to exist there for nothing (Although both should be admissible by the compiler).

One test to do is try this same program with another compiler. The other test is to force the conversion with a cast before the call to pthread_create, like so:

void * __cdecl (abc::*pPrintHello)(void *) = &abc::PrintHello ;
pthread_create(&threads[t], NULL, pPrintHello, (void *)t);

Share this post


Link to post
Share on other sites
Quote:
Original post by me_here_me
I successfully created a pointer to a function and executed the code using C. When I try to convert the same code into C++ it is causing trouble in making a pointer to a function.


C doesn't let you write anything remotely like that. You appear to be under the impression that "converting code into C++" means something like "putting stuff into classes". This is missing the point completely.

In C++, as is normal for languages that support 'classes', functions defined in the class "belong", by default, to some instance of the object. The class abc defines a data type, the same way that 'int' is a data type. Thus, a function of the class is called on an object.

When we write 'PrintHello', we simply get (a pointer to) the member function itself. The abstract concept. Now, our reason for passing this is so that the threading library can call the function in a new thread. Question: What object should the function be called on? Well, it may be obvious to you, but there's no reason for the compiler to have any good answer. The member-function-pointer doesn't contain that information.

To fix this, follow Sneftel's link. Read the whole page. It's a little harder to understand, maybe, but goes into more detail (including a summary of what I wrote above) and offers solutions.

Share this post


Link to post
Share on other sites
Thanks for replies.

Yeah, I was under the impression that arranging code into classes is C++. Anyway, I will go through the link send me Sneftel and re-write the code.

Thanks all for valuable information and input

Share this post


Link to post
Share on other sites

This topic is 3412 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this