Jump to content
  • Advertisement
Sign in to follow this  
Droid_999

Stuck on passing void *param in cpp

This topic is 570 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

Hi

I'm using the chipmunk physics library for my 2D Game - but I'm stuck on how to pass data via the void *param call.

In my collision handler I have this:

int passValue = -1;

cpSpaceAddPostStepCallback ( space, ( cpPostStepFunc ) postStepRemoveBullet, b, &passValue );

Which calls this as a callback

static void postStepRemoveBullet ( cpSpace *space, cpShape *shape, void *unused )
//-------------------------------------------------------------------
{
	int	bulletIndex;

	int passedValue = (int *)unused;
	
	bulletIndex = passValue;
	
	printf("bulletIndex [ %i ]\n", bulletIndex);    // prints -7426

Which gives me this warning ( it's an error using Visual Studio and fails to compile)

/src/system/sys_physicsCollisions.cpp:62:27: warning: invalid conversion from 'int*' to 'int' [-fpermissive]
  int passedValue = (int *)unused;

Two questions:

1 - How do I pass values to the callback function?; and

2 - Is it not working because the variable passValue in the first function is local, and disappears once that function is complete - meaning the address passed to the callback is invalid.

Thanks

Share this post


Link to post
Share on other sites
Advertisement

You may find an

invalid conversion from 'int*' to 'int'

in the line

int passedValue = (int *)unused;

If you compare the type on the left side of the = to the type on the right side.

 

As for callbacks, you pass arguments to the callback when you call it. You may wish to make use of std::function in order to simplify your life a bit.

Info and examples here: http://en.cppreference.com/w/cpp/utility/functional/function

Share this post


Link to post
Share on other sites

1 - How do I pass values to the callback function?

You pass a pointer, like you did in your example. In the callback you dereference the pointer to get the value.
 

2 - Is it not working because the variable passValue in the first function is local, and disappears once that function is complete - meaning the address passed to the callback is invalid.

That's one of your problems. You must make sure the pointer remains valid until the callback is removed, i.e. the lifetime of your param object must exceed the lifetime of the callback. Your other problem is that you're trying to assign an int pointer to an int. The pointer points to the address of the int, to get the actual value you must first cast from a void pointer to an int pointer and then dereference it:
 
int passedValue = *((int*)unused);
I would recommend reading up on pointers and object lifetime management, you might find this link a helpful start. Edited by Mussi

Share this post


Link to post
Share on other sites
void pointers are easier to understand if you think of them as abstract pointers. Just like an int pointer or a float pointer they are just a pointer(a 64 bit blob of memory on a 64 bit system) the only part that void affects is referring to what kind of type the pointer should dereference to.
 
Since they're abstract, that means you can't actually do anything meaningful with them because they just point to unknown memory, when you see void pointers in functions that means it is being used as an interface. I.e. you want to pass an int or a struct to a callback. The callback doesn't know what kind of data you want to pass ahead of time so it uses a void pointer to let you cast it back to the proper thing on the other side yourself. If you think about it the only other option would be to template the thing and have a different function signature for each type of callback you want to make.
 
As was pointed out the lifetime of your int isn't lasting, if it was just a function call then it would be fine, it would still be alive, but since you are setting a callback you can assume the callback could fire after the function the int is declared in has exited. Solutions to that are to either place the int somewhere else that will live long enough, or you can use new to create the actual integer and pass that into the void pointer, then delete it on the other side.
 
The other problem that multiple people pointed out is that your assignment code is almost correct but not quite. Your (int*) c-style cast should work, that give you a copy of the pointer that has been transformed to be an int pointer instead, the problem is you then try assigning a pointer to an int. Like was said above you want to dereference the pointer, i.e. copy the value of the thing it is pointing to instead of the pointer itself.
 
int passedValue = (int*)unused;
Can be more or less translated into:
int passedValue = int* unused;
Which is obviously wrong, you don't want to copy a pointer to an int.

 
int passedValue = *((int*)unused);
On the other hand can be roughly thought of as:
int passedValue = int unused;
More c++ friendly variant would be:
int passedValue = *(static_cast<int*>(unused));
Edited by Satharis

Share this post


Link to post
Share on other sites

How about: 

Void main()
{
void *unused;  // must remain in scope for lifetime of callback being hooked.
cpSpaceAddPostStepCallback(space,(cpPostStepFunc)postStepRemoveBullet,b,unused);
}

Share this post


Link to post
Share on other sites

 

 

void pointers are easier to understand if you think of them as abstract pointers. Just like an int pointer or a float pointer they are just a pointer(a 64 bit blob of memory on a 64 bit system) the only part that void affects is referring to what kind of type the pointer should dereference to.

Thanks - I understand that concept.

 

 

 

As was pointed out the lifetime of your int isn't lasting, if it was just a function call then it would be fine, it would still be alive, but since you are setting a callback you can assume the callback could fire after the function the int is declared in has exited. Solutions to that are to either place the int somewhere else that will live long enough, or you can use new to create the actual integer and pass that into the void pointer, then delete it on the other side.

Yes - this exactly.  I could use a variable with a scope more than the local function - but then I might as well just reference it from the callback function rather than pass it in.

I will look at the new suggestion - I like that as it means I can create the variable within the calling function without polluting with globals everywhere.

 

More c++ friendly variant would be:

int passedValue = *(static_cast<int*>(unused));

 

Thanks - I'll use this.

 

Cheers

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!