简体   繁体   中英

Find pointer/class using raw memory address

Before I ask my question, I want to say I realize there are some "similar" questions but nothing (that I can find) that specifically answers my question, so here goes.

I'm wondering if the following is possible. Lets say I create a new instance of a class, like so:

MyClass* classInstance = new MyClass();

I'm wondering if it's possible to store the raw memory address in say, a primitive type like an int. Then, somewhere in C++ no-mans-land where I do not have a pointer to classInstance , I can do something like this:

MyClass* myClassInstanceSomewhereInMemory = (MyClass*)0x12345678;
myClassInstanceSomewhereInMemory->workPlzKThx(); //Yay, it works!

In the case that this is possible, are there any risks involved? Is there any significant cost in overhead for such thing? I realize this pretty poor design, but unfortunately I am at the mercy of a third party here . So please do not chastise me for this, but feel free to chastise them . :)

An Explanation For This Madness
So just to explain a little further just why I have to do something as silly as this. I'm porting box2D over to an AIR Native Extension and as I referenced earlier, I am at the mercy of the AIR Runtime. The way it handles association between the native side and the Actionscript side is... messed up and further that, there are a ton of ridiculous rules for doing this association.

One such rule makes a real problem for situations like b2World->createBody() , which returns a pointer to a b2Body type (which has a private constructor). During this association I cannot simultaneously create a context to associate the new b2Body pointer with it, because during this call I am stuck within the context of b2World . So rather than slapping a bunch of dirty hacks together within classes like b2World and b2Body , I'm wondering if I can just use a primitive type like an int to store and return the memory address of the new b2Body .

I cannot return a pointer or a structure typed from C++ back to the Actionscript side. I can only associate with contexts... but I can return primitive types.

By far the easiest solution is a std::map<unsigned int, MyClass*> . Pretty much the only drawback is that after UINT_MAX allocations you'll have to go hunt for reusable values.

Many third party api will force you to use this type of pattern to pass data around. The only issue that you will have is that if you use a primitive type of int like you have suggested then if you ever compile for a 64 bit platform then this code will not be portable as the primitive type int will not hold the maximum address available on a 64 bit platform. You could use the built in type int_ptr which when compiled for 32 bit platforms is 32 bits and for 64 bit platforms is 64 bit to avoid this problem or you could use void* as the primitive type like the win32 CreateThread function or pthread_create function.

The appropriate value to be cast is intptr_t or uintptr_t , but I don't think that Adobe has these...

So putting C++ portability aside and just being practical, if you are in a 32-bit architecture, then an unsigned int should be fine, and in a 64-bit, an unsigned long , that is an integer long enough to hold the value of a pointer. The unsigned part is just to play safe, but you should be able to play without it also.

The main thing that you must be aware of is that the pointer types casted from and to the integer type must be identical. That is, the following is undefined behavior:

class  A {  };
class B : public A {};

B b;
A *pa = &b;
unsigned x = reinterpret_cast<unsigned>(&a);
B *pb = reinterpret_cast<B*>(x); //UB!

The last line should be:

A *pb = reinterpret_cast<A*>(x);

Or else:

B *pb = static_cast<B*>(reinterpret_cast<A*>(x));

Did you think of tagging this "AIR Native Extension" as well as C++? With the caveat that I don't know either box2d or AIR Native Extension it strikes me that you're probably trying to do something that others have attempted before and maybe something that Adobe prefer you not to do - possibly with good reason. For example:

I cannot return a pointer or a structure typed from C++ back to the Actionscript side. I can only associate with contexts... but I can return primitive types

Could you actually use a pointer within Actionscript or are you just retaining it in a primitive type so you can pass it back into the interface?

Maybe in this case you could store the pointer in an associative collection like a map and return the key as a handle . When you pass the handle back in, the C++ side could look up the pointer and cast appropriately given the context. That way you'd never pass the pointer per-se through the interface so you wouldn't be vulnerable to any pointer related issues.

Apologies if you were already thinking on these lines.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM