473,545 Members | 1,471 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

passing void function pointer

Hi,

I want to pass a function pointer that is a class member.

This is the fn I want to pass the function pointer into:

int Scheduler::Add( const unsigned long timeout, void* pFunction, void*
pParam)

There is another function where I make the call to the above function:

bool Scheduler::setS chedule(int interval, ComponentInterf ace&
CliComponent)
{
p_ClientCompone nt = &CliComponen t;

scheduler.Add(i nterval, CliComponent.ru nAction); // here

return true;
}

As you can see the above function is passed a reference to the
ComponentInterf ace class

I want to use the function runAction which is part of the
ComponentInterf ace class as a parameter to the add function. But this
fails. This is what I need to know, how can I pass this function to the
add function.
void CliComponent::r unAction()
This may be easy for some of you but its new to me, please help.
Thanks,
Enda

Sep 29 '05 #1
6 8811
* ke************* ***@yahoo.co.uk:
Hi,

I want to pass a function pointer that is a class member.

This is the fn I want to pass the function pointer into:

int Scheduler::Add( const unsigned long timeout, void* pFunction, void*
pParam)
'void*' is for data pointers. It's not compatible with function pointers.
The above therefore Undefined Behavior.

However, platform-specific APIs might have 'void*' function pointers.

Then you may be able to use a platform-specific reinterpret_cas t.
There is another function where I make the call to the above function:

bool Scheduler::setS chedule(int interval, ComponentInterf ace&
CliComponent)
{
p_ClientCompone nt = &CliComponen t;

scheduler.Add(i nterval, CliComponent.ru nAction); // here

return true;
}

As you can see the above function is passed a reference to the
ComponentInterf ace class

I want to use the function runAction which is part of the
ComponentInterf ace class as a parameter to the add function. But this
fails. This is what I need to know, how can I pass this function to the
add function.


You can not do that portably.

Non-portably: it depends on what the 'void*' pointer is assumed to be.

If it's assumed to be a straight C-style function pointer, then you need to
pass a pointer to freestanding function, that is, one that isn't a member or
if it is a member, is 'static', and it might look like this:

CliComponent* theCliComponent = 0;

void cliComponentRun Action()
{
assert( theCliComponent != 0 );
theCliComponent->runAction();
}

void* runActionCallba ck( CliComponent& aComponent )
{
theCliComponent = &aComponent;
return reinterpret_cas t<void*>( &cliComponentRu nAction );
}

and used like this:

bool Scheduler::setS chedule(
int interval, ComponentInterf ace& CliComponent
)
{
p_ClientCompone nt = &CliComponen t;

scheduler.Add( interval, runActionCallba ck( aComponent ), 0 );
return true;
}

where you should note that in addition to being non-portable and formally UB,
it's not thread-safe, and the result type 'bool' is most probably misleading
and unnecessary (unless this function must match a specific signature).

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Sep 29 '05 #2
Hi thanks for the reply,
I have decided to implement this using int pointers to the function
instead of void pointers.

int CliComponent::r unAction()
{
// do something
}

Do I still need to use the function callback.

Can I do this:

bool Scheduler::setS chedule( int interval, ComponentInterf ace&
CliComponent)
{
p_ClientCompone nt = &CliComponen t;

scheduler.AddTa sk(interval, p_ClientCompone nt->runAction, 0);
return true;
}

int Scheduler::Add( const unsigned long timeout, int* pFunction, void*
pParam)

This of course does not work.

Thanks again

Sep 29 '05 #3
<ke************ ****@yahoo.co.u k> wrote in message
news:11******** **************@ g44g2000cwa.goo glegroups.com.. .
I have decided to implement this using int pointers to the function
instead of void pointers.
int pointers are to point to ints. They can't point to functions.
int CliComponent::r unAction()
{
// do something
}

Do I still need to use the function callback.

Can I do this:

bool Scheduler::setS chedule( int interval, ComponentInterf ace&
CliComponent)
{
p_ClientCompone nt = &CliComponen t;

scheduler.AddTa sk(interval, p_ClientCompone nt->runAction, 0);
return true;
}


I don't understand your question clearly. In your original post, you called
runAction "a part of the ComponentInterf ace class." Does that mean that
there is a function pointer member in each object?

If so, here is an example for the function pointer that is a public member:

#include <iostream>

int twice(int number)
{
return number * 2;
}

typedef int (*Function)(int );

class Foo
{
public:

// Public data member is not good!
Function function_;

explicit Foo(Function function)
:
function_(funct ion)
{}
};

// This function receives a reference to an object and calls a function,
// which is "a part of" that object.

void user(Foo const & foo)
{
std::cout << (foo.function_) (2) << '\n';
}

int main()
{
Foo foo(twice);
user(foo);
}

When you said "a part of the ComponentInterf ace class," if you actually
meant "a part of the class," then may be you are talking about member
function pointers. Here is an example:

#include <iostream>

class Foo
{
public:

int twice (int number) { return number * 2; }
int thrice(int number) { return number * 3; }
};

typedef int (Foo::*MemberFu nction)(int);

void user(Foo & foo, MemberFunction function)
{
std::cout << (foo.*function) (2) << '\n';
}

int main()
{
Foo foo;
user(foo, &Foo::twice) ;
user(foo, &Foo::thrice );
}

Ali

Sep 29 '05 #4
ke************* ***@yahoo.co.uk wrote:
Hi thanks for the reply,
I have decided to implement this using int pointers to the function
instead of void pointers.

int CliComponent::r unAction()
{
// do something
}

Do I still need to use the function callback.

Can I do this:

bool Scheduler::setS chedule( int interval, ComponentInterf ace&
CliComponent)
{
p_ClientCompone nt = &CliComponen t;

scheduler.AddTa sk(interval, p_ClientCompone nt->runAction, 0);
return true;
}

int Scheduler::Add( const unsigned long timeout, int* pFunction, void*
pParam)

This of course does not work.

Thanks again


The question is how to specify a member function pointer as a callback
routine. The problem with passing a member function pointer such
&ComponentInter face::runAction is that the function accepting the
callback needs to expect a member function pointer for that particular
class, in this case, ComponentInterf ace:

int Scheduler::Add( const unsigned long timeout,
int (ComponentInter face::*)())

Since the Add() method has to know the member function's class, then
there is little reason for it not to know which member function in that
class it should be calling. So why bother with the callback at all? Why
not just pass a ComponentInterf ace pointer? In other words, because a
member function pointer is class-specific, it is not suitable for use
as a generic callback routine.

There is a solution however. Most callbacks consist of a function
pointer and a "user data" pointer that is passed to the function when
it is called. This data pointer allows the callback routine to
"recover" an object and then call its appropriate method. Such an
approach would look something like this:

The function accepting the callback also accepts a user data pointer:

int Scheduler::Add( const unsigned long timeout,
int (*inCallback)(v oid *),
void *inUserData)
The client specifies the callback like so:

{
ComponentInterf ace theComp;

scheduler->Add(0, MyCallBack, &theComp);
and the callback routine itself:

int MyCallBack( void *inMyData)
{
ComponentInterf ace * component;

component = static_cast<Com ponentInterface *>(inMyData);
component->runAction();
}

This technique is not ideal since type information is lost and then
recovered. But it does help to prevent unnecessary dependencies
between the callback and the caller.

Greg

Sep 29 '05 #5
On 29 Sep 2005 15:27:14 -0700, "Greg" <gr****@pacbell .net> wrote:
int MyCallBack( void *inMyData)
{
ComponentInterf ace * component;

component = static_cast<Com ponentInterface *>(inMyData);
component->runAction();
}


reinterpret_cas t is what you want.

--
Bob Hairgrove
No**********@Ho me.com
Sep 30 '05 #6
Bob Hairgrove wrote:
On 29 Sep 2005 15:27:14 -0700, "Greg" <gr****@pacbell .net> wrote:
int MyCallBack( void *inMyData)
{
ComponentInterf ace * component;

component = static_cast<Com ponentInterface *>(inMyData);
component->runAction();
}


reinterpret_cas t is what you want.


A static_cast is fine. A program can always safely convert a object
pointer to a void pointer and back again.

In reality, it makes no difference. Neither a static_cast or
reinterpret_cas t generate any machine instructions. They are both
no-ops used to placate the compiler's type checking. Therefore when
choosing between them, one should favor a static_cast if possible. A
static cast communicates that the cast has reasonable assurance of
being safe. Since the void * conversion is a supported conversion, a
static_cast is the one to use.

Of course, if the void * is pointing to a different class of object
than the one expected, the program is in trouble. Using a
reinterpret_cas t instead of static_cast would of course not have
changed that fact, and in fact would not have changed anything at all.

Greg

Sep 30 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

58
10064
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of code... TCHAR myArray; DoStuff(myArray);
6
8196
by: bob_jenkins | last post by:
{ const void *p; (void)memset((void *)p, ' ', (size_t)10); } Should this call to memset() be legal? Memset is of type void *memset(void *, unsigned char, size_t) Also, (void *) is the generic pointer type. My real question is, is (void *) such a generic pointer type that it
9
5281
by: Juggernaut | last post by:
I am trying to create a p_thread pthread_create(&threads, &attr, Teste, (void *)var); where var is a char variable. But this doesnt't work, I get this message: test.c:58: warning: cast to pointer from integer of different size. Now I thought that when it was a void I could pass anything? Thing is it works when I use an int, but in this...
11
4432
by: truckaxle | last post by:
I am trying to pass a slice from a larger 2-dimensional array to a function that will work on a smaller region of the array space. The code below is a distillation of what I am trying to accomplish. // - - - - - - - - begin code - - - - - - - typedef int sm_t; typedef int bg_t; sm_t sm; bg_t bg;
17
3575
by: Charles Sullivan | last post by:
The library function 'qsort' is declared thus: void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); If in my code I write: int cmp_fcn(...); int (*fcmp)() = &cmp_fcn; qsort(..., fcmp); then everything works. But if instead I code qsort as:
1
3261
by: Shawn | last post by:
As if it won't be clear enough from my code, I'm pretty new to C programming. This code is being compiled with an ANSI-C compatible compiler for a microcontroller. That part, I believe, will be irrelavent. My syntax is surely where I am going wrong. I'd like to be able to call this routine to read different values from another device. ...
12
5372
by: Mike | last post by:
Consider the following code: """ struct person { char *name; int age; }; typedef struct person* StructType;
3
2600
by: dice | last post by:
Hi, In order to use an external api call that requires a function pointer I am currently creating static wrappers to call my objects functions. I want to re-jig this so I only need 1 static wrapper function. I would prefer to be able to pass the member function as a void* to the static wrapper but I suspect this may not even be possible....
2
2170
by: sonaliagr | last post by:
I am trying to update a msg array in function by passing the address but it is showing an error. and also, i want the value of msg array to be accessible to the full code that is inside the main function...I hope i am making sense...Please look at the code and help me in pointing out the error.. #include<stdio.h> #include<stdlib.h>...
0
7465
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7656
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7805
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7416
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7752
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
4944
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3449
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
1878
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1013
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.