Rahul Iyer
Rahul Iyer

Reputation: 21005

How to determine the type (Class) of a pointer being returned as void *?

I'm working on a Box2d project.

In a particular class constructor, I do:

this->body->SetUserData(this);

where body is a member of this class. body is of type b2Body.

Later on, I call a method:

body->GetUserData();

GetUserData() returns void*

How do I determine what type of class void* is pointing to ?

EDIT: For those who don't use Box2d, you can set the user data to your wrapper class which holds all the non-physics related logic etc, while b2Body represents a physics body.

EDIT: For example, in Objective-C , one would cast void* to NSObject* and then call isMemberOf to determine whether it is of a particular type.

Upvotes: 2

Views: 126

Answers (2)

rioki
rioki

Reputation: 6118

The short answer, as John Zwinck points out, is you can't.

The use of void* is an old C trick how to add user configurable data to a library. This is normally used when integrating a middleware library into a bigger software. The basic assumption here is that you know what type is behind the void*. In my experience with wrapping ODE and Bullet, this works out quite well.

There are basically two cases and with each you know what basic type is behind that void*:

In the first case you have a one to one correlation between a body or geometry to an object in the wrapping software. In this case you would simply reinterpret_cast to the wrapping object.

In the second case the body or geometry is contained in some "game object". This can be any object within the scene. But normally all "object within the scene" share a common base class. Here you simply assume that you can reinterpret_cast to the base class. Now you have an object in the hand, what you do from here is up to you. You can either call virtual methods on it, use dynamic_cast or some homebrew reflection.

Upvotes: 1

John Zwinck
John Zwinck

Reputation: 249133

There's nothing intrinsic to C++ which will let you determine the type pointed to by a void*. Your best options are probably:

  1. Make an abstract base class which all your userdata items will derive from. Maybe you already have one. Then you can assume the void* will always be a type derived from that base, and use it accordingly.
  2. Make a discriminated union type (or use Boost.Variant), and always have the void* point to one of those.
  3. Make a small struct which the void* will always point to an instance of, and make that struct be the first member of everything you assign to the void* (this will only work if you're doing more C-style programming, and the classes have no bases to interfere with the alignment).

Upvotes: 3

Related Questions