C Board  

Go Back   C Board > General Programming Boards > C++ Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 03-17-2009, 11:47 AM   #1
Registered User
 
Join Date: Mar 2009
Posts: 8
Exclamation What is function(void *arg)

What is the (void *arg)? How does it work, and how would I access the data of a void type?
CorX is offline   Reply With Quote
Old 03-17-2009, 12:19 PM   #2
CSharpener
 
vart's Avatar
 
Join Date: Oct 2006
Posts: 5,242
it is just a general pointer passing to the function, your function should know what is the actual type of the pointer - and cast it apropriatly before accessing the data.

It is mostly used in the Callbacks, when library is provided with CB address and some context address.
Library does not need to know the type of the data - so the pointer is stored as void* and supplied to the CB, when it is called from the library code

the CB - which is part of the application code - knows exactly what is the data type passed as a context and could cast the pointer accordingly
__________________
If I have eight hours for cutting wood, I spend six sharpening my axe.

Last edited by vart; 03-17-2009 at 12:23 PM.
vart is offline   Reply With Quote
Old 03-17-2009, 12:24 PM   #3
Registered User
 
Join Date: Mar 2009
Posts: 8
Thanks, I understand know.
CorX is offline   Reply With Quote
Old 03-17-2009, 12:37 PM   #4
Guest
 
Sebastiani's Avatar
 
Join Date: Aug 2001
Posts: 4,923
This technique isn't used as often in C++ as it is in C, but there are certain situations where it's unavoidable. A typical usage is with callback functions. Lets say you have a shape-drawing library. You want to allow the user to decide what to do when a pixel needs to be drawn. You have no idea what data structures the client code requires to accomplish that so you simply have them pass a pointer to their data. Here's a somewhat contrived example:

Code:
// library code

typedef void ( * callback )( int, int, void* ); 

void draw_some_shape( rectangle* bounds, callback function, void* data )
{
    for( int r = bounds->top; r < bounds->bottom; ++r )
        for( int c = bounds->left; c < bounds->right; ++c )
            if( inside( r, c ) )
                callback( r, c, data );
}    

// client code

struct image_data
{
    int image[ HEIGHT ][ WIDTH ], color;
};

void draw_pixel( int row, int column, void* data )
{
    image_data* image = ( image_data* )data;
    image_data->image[ row ][ column ] = image_data->color;    
}

int main( void )
{
    image_data data;
    data.color = hsv( 0.333, 0.5, 0.5 );
    rectangle bounds;
    bounds.top = HEIGHT / 2;
    bounds.left = WIDTH / 2;    
    bounds.bottom = HEIGHT;
    bounds.right = WIDTH;
    draw_some_shape( &bounds, draw_pixel, &data );
    // do something useful with the image
    return 0;
}

Last edited by Sebastiani; 03-17-2009 at 12:41 PM. Reason: corrections
Sebastiani is offline   Reply With Quote
Old 03-17-2009, 12:50 PM   #5
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,366
Quote:
Originally Posted by Sebastiani
You have no idea what data structures the client code requires to accomplish that so you simply have them pass a pointer to their data.
That said, this is one situation where it is avoidable in C++ by means of C++ templates, e.g.,
Code:
// library code

template<typename T, typename Callback>
void draw_some_shape( const rectangle& bounds, Callback function, T& data )
{
    for( int r = bounds.top; r < bounds.bottom; ++r )
        for( int c = bounds.left; c < bounds.right; ++c )
            if( inside( r, c ) )
                function( r, c, data );
}

// client code

struct image_data
{
    int image[ HEIGHT ][ WIDTH ], color;
};

void draw_pixel( int row, int column, image_data& data )
{
    image_data.image[ row ][ column ] = image_data.color;
}

int main( void )
{
    image_data data;
    data.color = hsv( 0.333, 0.5, 0.5 );
    rectangle bounds;
    bounds.top = HEIGHT / 2;
    bounds.left = WIDTH / 2;
    bounds.bottom = HEIGHT;
    bounds.right = WIDTH;
    draw_some_shape( bounds, draw_pixel, data );
    // do something useful with the image
    return 0;
}
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is online now   Reply With Quote
Old 03-17-2009, 12:52 PM   #6
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
This can be avoided with template, as shown below:
Code:
// library code

template<typename T, typename Callback_t>
void draw_some_shape( rectangle* bounds, Callback_t function, T& data )
{
    for( int r = bounds->top; r < bounds->bottom; ++r )
        for( int c = bounds->left; c < bounds->right; ++c )
            if( inside( r, c ) )
                callback( r, c, data );
}    

// client code

struct image_data
{
    int image[ HEIGHT ][ WIDTH ], color;
};

void draw_pixel( int row, int column, image_data* data )
{
    image_data->data[ row ][ column ] = image_data->color;    
}

int main()
{
    image_data data;
    data.color = hsv( 0.333, 0.5, 0.5 );
    rectangle bounds;
    bounds.top = HEIGHT / 2;
    bounds.left = WIDTH / 2;    
    bounds.bottom = HEIGHT;
    bounds.right = WIDTH;
    draw_some_shape( &bounds, &draw_pixel, &data );
    // do something useful with the image
    return 0;
}
There is little excuse for void* in C++, except for calling C functions.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 03-17-2009, 01:14 PM   #7
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,381
Quote:
Originally Posted by Elysia View Post
This can be avoided with template, as shown below:
The method you and Laserlight are talking about is definitely a good one, but it still, in theory, allows the possibility for the callback driver to poke around inside the T object when it shouldn't. In practice, this would be extremely difficult because you don't know what's in there, but a void * completely guarantees that the code won't touch it, since it has no idea what type it is (even as a template parameter).

Normally though, I'd define a callback API like this:

Code:
class Callback
{
public:
    virtual ~Callback() {}

    virtual void DoIt() = 0;
};

void DriveTheCallback(Callback *cb)
{
    cb->DoIt();
}
The actual callback just inherits from Callback and overrides DoIt().
__________________
"Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot
brewbuck is offline   Reply With Quote
Old 03-17-2009, 01:25 PM   #8
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
Well, I suppose that may be, but then we would get into X vs Y. Your solution might hide the object, but it's also slower due to being dynamic polymorphism as opposed to static polymorphism.
It also means more work, but hey, no solution is ever perfect.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 03-17-2009, 01:31 PM   #9
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,381
Quote:
Originally Posted by Elysia View Post
Well, I suppose that may be, but then we would get into X vs Y. Your solution might hide the object, but it's also slower due to being dynamic polymorphism as opposed to static polymorphism.
It also means more work, but hey, no solution is ever perfect.
Static polymorphism would not allow for loading a plug-in which might implement the callback. Yep, always a tradeoff.
__________________
"Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot
brewbuck is offline   Reply With Quote
Reply

Tags
args, pointers, void

Thread Tools
Display Modes

Forum Jump


All times are GMT -6. The time now is 09:50 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22