Casting a double to an IDirect3DDevice9*?

Started by
7 comments, last by L. Spiro 9 years, 6 months ago

Hi Guys,

I have a known 'double' (which is an address) for an IDirect3DDevice9 interface (supplied by a 3rd party API). But, I need to cast this back to an IDirect3DDevice9* so my DLL can make use if it properly.

I have tried all sorts of things but can't get it to cast back properly.

Any advice on how I would do this would be awesome!

Thank you in advance smile.png

[edit] there is also the option I could get it as a char* as well if that helps out my options :)

Advertisement

It's not a "double" - if your application is 32-bit, it's probably a "double word", or DWORD.

To be compatible with both 32-bit and 64-bit, you (and the 3rd party API as well) should use LONG_PTR as type, and you should static_cast it to LPD3DDEVICE9.

Also, what problem are you having exactly? Static casting by itself should always work, so if your IDirect3DDevice9* interface pointer is not useable later, perhaps the DWORD from your 3rd party API is not what you think it is (assuming you weren't trying to cast to it from a "double", which actually does a float-to-int numeric conversion instead).

Ah ok, It is probably a DWORD (been a long day). Actually a REAL is what it is defined as in the 3rd party API as it turns out. Does that sound right?

The problem is I keep getting an invalid pointer, so my DLL causes an immediate crash.

Ah ok, It is probably a DWORD (been a long day). Actually a REAL is what it is defined as in the 3rd party API as it turns out. Does that sound right?

The problem is I keep getting an invalid pointer, so my DLL causes an immediate crash.

I don't know what the REAL type is. It's not a standard C or C++ type and does not appear in the Windows Data Types page. But a real is a numeric type representing a point on the real line (if you don't know what the real line is, "all the numbers" is a sufficiently accurate description) and is generally implemented as a floating-point type. So, no, I don't think that sounds right at all. What API is this? It must not be very sane if it returns pointers as floating-point values.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”


Actually a REAL is what it is defined as in the 3rd party API as it turns out. Does that sound right?

Stop guessing. Either you know for sure that it's supposed to be a pointer to ID3DDevice9 or not? You can't just take API return values and assume they are something else. And just because you cast something to another C++ type, doesn't mean it will just magically take on the properties and functionality of that type. The API you're using should clearly document the parameter/return value you're trying to use - look it up.


[edit] there is also the option I could get it as a char* as well if that helps out my options smile.png

No, it doesn't. Stop guessing. The proper way to represent typeless pointers (if that's what you're trying to do, and without relying on the Windows Data Types) is with void*... If you think you can use the char* type as well (although, if you can define the source data type as any type, why not just use LPD3DDEVICE9 or ID3Device9* directly?), then you can probably do a reinterpret_cast<LPD3DDEVICE9> on it, but it is bad practice to do this. Just define the source data type as LPD3DDEVICE9 - the way it's supposed to be used - and then you won't have to do a cast at all.

tonemgub - I am not guessing.

I know for a fact that the two types are either a straight pointer or a REAL (Microsoft's definition).

The thing is I have created and extension for GameMaker: Studio that makes use of the IDirect3DDevice9*. It works perfectly and has done so for over a year.

I am now trying to get my extension working in the debarcle that is Enigma (supposed open source clone of GM:S).

As it turns out their (Enigma's) implementation of how DLL's are used is screwed up. After conferring with the lead devs over there, it turns out that I know more about the implementation than they do. And as a result their 'types' are all over the place.

So, we can probably disregard my entire post now. As their API is somewhat corrupt and the conversion of my DLL has no possibility of working.

I spent several hours this evening directly modifying the Enigma source (along with the lead dev over IRC). In the end, we agreed the implementation is completly wrong.

So, sorry about the vagueness of my original posts guys. Many appologies :)


So, sorry about the vagueness of my original posts guys. Many appologies smile.png

No problem Sorry I sounded a bit harsh. It sure sounds like you (or the guys who provided you that API) were just guessing, though... Who knows what they were putting into that pointer.

But if you are both sure that it's a pointer to a IDirect3DDevice9*, AND that it was created on the same thread as the thread that you are trying to use it on (especially, it should not come from a separate process), then reinterpret_cast<LPD3DDEVICE9> should definitely work...

My guess is however, that it's not a pointer to IDirect3DDevice9. Most plugin APIs usually have their own data types - I don't think they would allow you access to a IDirect3DDevice9 directly, of all things. Ar you sure they specifically said "pointer to IDirect3DDevice9" and not something vague, like "pointer to device"?

Microsoft only has a REAL data type in their SQL database products, AFAIK - if you (or they) are passing this pointer through a database, it probably isn't coming from the same process? At least, there's no point in using a database for passing variables between different subroutines of the same process - let alone, passing data pointers as REAL values, and let alone passing pointers through a database interface.

I looked up the data types you mentioned, in relation with GameMaker, and just for the purpose of getting somewhere with this, perhaps the most appropriate datatype to use is GML's Pointer type: http://docs.yoyogames.com/source/dadiospice/002_reference/001_gml%20language%20overview/data%20types.html ?

(And no, in this case, REAL is not a data type defined by Microsoft - it's a GameMaker GML data type, by the looks of it - the guys you were in touch with were probably talking about GML data types, while you were talking about C++).

And I think this is your post: http://enigma-dev.org/forums/index.php?topic=2258.msg22578#new :)

So just change the double to void*, and as they also recommended, use reinterpret_cast...

A possibility is that it's a pointer stashed in a 32-bit number type (I'll call it a REAL for now but it could be typedef'ed as anything), in which case you might try something like this:

union {

REAL number;

IDirect3DDevice9 *device;

} stuff;

stuff.number = ISummonTheWeirdAPIToDoMagicStuff ();

return stuff.device;

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

One does not cast pointers to DWORD. One casts a pointer to UINT_PTR.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

This topic is closed to new replies.

Advertisement