views:

532

answers:

7

i need to convert pointers to long (SendMessage()) and i want to safely check if the variable is correct on the otherside. So i was thinking of doing dynamic_cast but that wont work on classes that are not virtual. Then i thought of doing typeid but that will work until i pass a derived var as its base.

Is there any way to check if the pointer is what i am expecting during runtime? Is there a way i can use typeid to see if a pointer is a type derived from a particular base?

A: 

PTLib ( http://sourceforge.net/projects/opalvoip/ ) uses a PCLASSINFO macro to define relations between classes. This provides functions like IsDescendant and GetClass.

You could probably implement something similar.

DanJ
A: 

dynamic_cast works by checking the signature of the virtual method table. If you have no virtual methods, you have no VMT, so as you say dynamic_cast won't work. However, if you have no VMT, you have absolutely NO knowledge about the object being pointed to.

Your best bet is to require that pointers are to classes with at least one virtual method, even if it's a dummy. Dynamic cast will work then.

Roddy
A: 

I don't understand yet what your question is about.

  • If it is whether or not you can be sure that casting to a long and back will yield the same value, view http://stackoverflow.com/questions/311102/safely-checking-the-type-of-a-variable#311189
    Given the "Rules for using Pointers" MS-Site the other Answerer linked to, the right type to cast to is UINT_PTR. So you do UINT_PTR v = reinterpret_cast<UINT_PTR>(ptr); to cast to a integral type, and do the reverse to cast it back to the pointer again. The C++ Standard guarantees that the original value is restored. (see the link i gave above for my explanation of that). That Microsoft site by the way also says that WPARAM and LPARAM change their size depending on the platform. So you could just use that variable v and SendMessage it.
  • If it is how you can check on the other side whether or not the pointer (converted to some pointer type) points to some object, the answer is you can't. Since you are apparently not sure which pointer type was used to send it, you cannot check on the receiving side what the dynamic type the pointer points to is. If you know the type the pointer had on the sender side, your check would be not required in the first place.
Johannes Schaub - litb
A: 

If all you have is a long, then there's not really much you can do. There is no general way to determine whether an arbitrary number represents a valid memory address. And even if you know it's a valid memory address, there is no way to determine the type of the thing the pointer points to. If you can't be sure of the real type of the thing before its address was cast to long, then you can't be sure that it's going to be safe to cast the long to whatever type you plan on casting it to.

You'll just have to trust that the sender of the message has sent you a valid value. The best you can do is to take some precautions to reduce the consequences to your own program when it receives a bogus value.

Rob Kennedy
+1  A: 

You cannot use typeid. It will result in an Access Violation if you get garbage instead of a valid pointer, so your check is nonsensical.

What you should do, is wrap your SendMessage and the code which processes the message into a single type-safe interface. This way you will be unable to pass unexpected things to SendMessage, and will not need any checks on receiving side.

C++ type system works at compile time. Once you cast a pointer to a long, you loose all type information. A long is just so much bits in memory; there is no way you can identify that it was pointing to an object.

atzz
+2  A: 

Your reference to SendMessage() makes i sounds like MS Windows is your platform and then the Rules for Using Pointers (Windows) is recommended reading. It details the PtrToLong and PtrToUlong functions and other things Microsoft provide for you in situations like this.

divideandconquer.se
A: 

In Windows, MFC provides a method to check if a given pointer is pointing to a valid memory location (this is done by trapping segfault). I do not remember the function name, but it's there. Still, it does not ensure that the contents of the memory pointed to are valid. It may still have invalid VMT and crash your code. Of course, you can trap the segfault yourself (see MS Knowledge Base)

As for checking if something belongs to a type, you must have a base class to start with. If you make the destructor of base class "virtual", all derived classes will have VMTs.

If you must avoid VMT at all costs, you have to have some sort of descriminator that tells you what you're dealing with, such as event type in MS Windows events.

Arkadiy