Sign in to follow this  
VanillaSnake21

Set Callback from class

Recommended Posts

Hi, I'm using Newton Pshyics SDK and it requires you to set a callback for one pf it's functions, I'm trying to wrap everything in my own class, but when I try to set the callback from within the class I am getting a compiler error that says that the parameter of a callback cannot be converted to a certain function. But when I use a function that is not in a class to set the callback, it works fine, how can I fix this problem. Thanks.

Share this post


Link to post
Share on other sites
Quote:
Original post by VanillaSnake21
Hi, I'm using Newton Pshyics SDK and it requires you to set a callback for one pf it's functions, I'm trying to wrap everything in my own class, but when I try to set the callback from within the class I am getting a compiler error that says that the parameter of a callback cannot be converted to a certain function. But when I use a function that is not in a class to set the callback, it works fine, how can I fix this problem. Thanks.
It sounds like you're trying to submit a class member function as the callback, which almost certainly won't work (I'm making some assumptions here about the Newton API).

Just so we have a little more to go on, perhaps you could post a bit of code, e.g. the class in question, the code where you set the callback, and perhaps the declaration of the corresponding Newton API function (or maybe a link to where we can read about it). Information about the purpose of the callback would be useful as well.

Given some more information, I'm sure the gurus here will be able to offer some good suggestions as to how you might work around the member function pointer problem.

Share this post


Link to post
Share on other sites
Class member functions are not the same as "plain" functions; they employ a different calling convention - __thiscall vs __stdcall - to allow for the implicit passing of the pointer to the current object. Static member functions, however, use the __stdcall convention because they belong to the class and do not have access to instance members, so you can pass a static member function to the physics SDK.

If you need access to a class object instance, you will need some mechanism for registering an association between a pointer to an object instance and an index available to the physics SDK, which it passes to the static member function. The static function uses that index to retrieve the object instance pointer. The canonical example is abstraction of Win32 HWND into classes.

Share this post


Link to post
Share on other sites
[source lang = cpp]
void PhysicsObj::PhysicsApplyForceAndTorque(const NewtonBody* Body, float Gravity)
{
dFloat Ixx;
dFloat Iyy;
dFloat Izz;
dFloat Mass;

NewtonBodyGetMassMatrix(Body, &Mass, &Ixx, &Iyy, &Izz);
D3DXVECTOR3 force(0.0f, Mass* Gravity, 0.0f);
NewtonBodySetForce(Body, force);
}


void PhysicsObj::SetGravityCallback()
{


NewtonBody* Body;
NewtonBodySetForceAndTorqueCallback(Body, PhysicsApplyForceAndTorque);
}

these are my funtions which are within a single class, and they are both static, but I'm still getting the same error.



Edit: these are the decls in .h file



static void PhysicsApplyForceAndTorque(const NewtonBody* Body, float Gravity);
static void SetGravityCallback();

Share this post


Link to post
Share on other sites
Quote:
Original post by Oluseyi
Class member functions are not the same as "plain" functions; they employ a different calling convention - __thiscall vs __stdcall - to allow for the implicit passing of the pointer to the current object. Static member functions, however, use the __stdcall convention because they belong to the class and do not have access to instance members, so you can pass a static member function to the physics SDK.
It's more than that though. Non-static class member function pointers typically are larger than function pointers. The size of the non-static class member function pointer depends heavily on the class, if the function is virtual if the class inherits from another class, if the parent class has a virtual function of the same signature, if virtual inheritance is used in the inheritance tree, etc.

Share this post


Link to post
Share on other sites
Quote:
Original post by Washu
Quote:
Original post by Oluseyi
Class member functions are not the same as "plain" functions; they employ a different calling convention - __thiscall vs __stdcall - to allow for the implicit passing of the pointer to the current object. Static member functions, however, use the __stdcall convention because they belong to the class and do not have access to instance members, so you can pass a static member function to the physics SDK.
It's more than that though. Non-static class member function pointers typically are larger than function pointers. The size of the non-static class member function pointer depends heavily on the class, if the function is virtual if the class inherits from another class, if the parent class has a virtual function of the same signature, if virtual inheritance is used in the inheritance tree, etc.


But I'm not inheriting my class, and both methods are static.

Share this post


Link to post
Share on other sites
Quote:
Original post by VanillaSnake21
But I'm not inheriting my class, and both methods are static.


Show the code and the exact error, please. We're not psychic.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Zahlman
Quote:
Original post by VanillaSnake21
But I'm not inheriting my class, and both methods are static.


Show the code and the exact error, please. We're not psychic.


The code is already shown, unless you want me to post up the entire class header ,and implementation, which i think would be pretty useless since those two lines is where all the action is taking place, and the error is


c:\Documents and Settings\Owner\My Documents\Visual Studio Projects\Physics Tester 2003\Physics.cpp(34) :
error C2664: 'NewtonBodySetForceAndTorqueCallback' : cannot convert parameter 2 from 'void (const NewtonBody *,float)' to 'NewtonApplyForceAndTorque'
None of the functions with this name in scope match the target type

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
Original post by VanillaSnake21
But I'm not inheriting my class, and both methods are static.


Show the code and the exact error, please. We're not psychic.


The code is already shown, unless you want me to post up the entire class header ,and implementation, which i think would be pretty useless since those two lines is where all the action is taking place, and the error is


c:\Documents and Settings\Owner\My Documents\Visual Studio Projects\Physics Tester 2003\Physics.cpp(34) :
error C2664: 'NewtonBodySetForceAndTorqueCallback' : cannot convert parameter 2 from 'void (const NewtonBody *,float)' to 'NewtonApplyForceAndTorque'
None of the functions with this name in scope match the target type

Sorry for two post, pressed post twice

Share this post


Link to post
Share on other sites
Quote:
Original post by VanillaSnake21
Quote:
Original post by Anonymous Poster
I'm smelling the perfect place to use Boost to send Newton that class function.


boost?
If you're asking what Boost is, it's a collection of C++ libraries that compliment and extend the standard C++ library (some of these libraries are actually on their way to becoming part of the SC++L).

Before considering Boost though, let's take a look at your error:
c:\Documents and Settings\Owner\My Documents\Visual Studio Projects    Physics Tester 2003\Physics.cpp(34) :
error C2664: 'NewtonBodySetForceAndTorqueCallback' : cannot convert parameter 2
from 'void (const NewtonBody *,float)' to 'NewtonApplyForceAndTorque'
None of the functions with this name in scope match the target type
It looks to me as if Newton is expecting a pointer to a function with a different signature than that of your callback function. A quick Google search for NewtonApplyForceAndTorque turns up the following:
typedef void (*NewtonApplyForceAndTorque) (const NewtonBody* body);
Which matches yours, except for the second parameter of type float.

So the short answer is, drop the second parameter from your function and it will probably work. I can't really give you the long answer without investigating the Newton API though (I'm not really sure how the callback is supposed to work, or what led you to believe there was supposed to be a 'gravity' parameter).

As for Boost, I'm not sure a Boost library can be applied directly here (emphasis on 'directly'). NewtonBodySetForceAndTorqueCallback() is expecting a pointer to a function with a specific signature, no more, no less, and I don't think there's any way to 'trick' the Newton API into accepting a more sophisticated delegate object in its place (now watch me be proven wrong by one of our resident gurus :). There are certainly more sophisticated things that you could do on your end with respect to callbacks, delegates, and so forth, but I can't really comment on that further without being more familiar with the Newton API.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Quote:
Original post by VanillaSnake21
Quote:
Original post by Anonymous Poster
I'm smelling the perfect place to use Boost to send Newton that class function.


boost?
If you're asking what Boost is, it's a collection of C++ libraries that compliment and extend the standard C++ library (some of these libraries are actually on there way to becoming part of the SC++L).

Before considering Boost though, let's take a look at your error:
c:\Documents and Settings\Owner\My Documents\Visual Studio Projects    Physics Tester 2003\Physics.cpp(34) :
error C2664: 'NewtonBodySetForceAndTorqueCallback' : cannot convert parameter 2
from 'void (const NewtonBody *,float)' to 'NewtonApplyForceAndTorque'
None of the functions with this name in scope match the target type
It looks to me as if Newton is expecting a pointer to a function with a different signature than that of your callback function. A quick Google search for NewtonApplyForceAndTorque turns up the following:
typedef void (*NewtonApplyForceAndTorque) (const NewtonBody* body);
Which matches yours, except for the second parameter of type float.

So the short answer is, drop the second parameter from your function and it will probably work. I can't really give you the long answer without investigating the Newton API though (I'm not really sure how the callback is supposed to work, or what led you to believe there was supposed to be a 'gravity' parameter).

As for Boost, I'm not sure a Boost library can be applied directly here (emphasis on 'directly'). NewtonBodySetForceAndTorqueCallback() is expecting a pointer to a function with a specific signature, no more, no less, and I don't think there's any way to 'trick' the Newton API into accepting a more sophisticated delegate object in its place. There are certainly more sophisticated things that you could do on your end with respect to callbacks, delegates, and so forth, but I can't really comment on that further without being more familiar with the Newton API.


Thank you so much, that was it, I don't know how I overlooked it, I probably tried everything except changing the signature. The reason i had Gravity in there is because the method has to be static, and so I have to make Gravity static as well to reference it, but if Gravity is static it will be shared among every instance of the class (I think) and I might want different objects to be infuenced by different gravity constants. Anyways thanks again :)

Share this post


Link to post
Share on other sites

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