Archived

This topic is now archived and is closed to further replies.

sprinter_trueno

run-time cast possible in c++ ?

Recommended Posts

Hi ppl, as stated in the topic I''d like to know whether it is possible to change a type at runtime. I have a pointer pointing to an array. The type of the pointer should vary (char, short, int) depending on certain circumstances so that I can read back a selective amount of data from the array. Is that possible somehow ? Lorenz

Share this post


Link to post
Share on other sites
of course it is. What exactly is your level of knowledge in C++? Casting is a basic staple of understanding it.

Share this post


Link to post
Share on other sites
u32 MyArray[10];
u32 *MyPointer=MyArray;
(u8*)MyPointer=MyArray;
(u16*)MyPointer=MyArray;

i _hope_ this works *G*

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
if you want a generic object type that can hold different kinds of objects, check this out
http://www.cuj.com/documents/s=8034/cuj0010cacciola/cacciola.htm

for general casting, check out
http://www.c-view.org/tech/pattern/cpptips/TypeCheck.html

sorry for ap:ing, i´m in a hurry

later
jens.

Share this post


Link to post
Share on other sites
maximAL: nice try , thanks anyways.
AP: I'm on it, but didn't find anything yet.
daerid: I'm still waiting

Just to make things clear.


    
char Array[4];
void* pArray = (void*)Array;
// Somewhere else

if(...)
{
// Change the type of the pointer somehow to int*

// ...

}
else if(...)
{
// Change the type of the pointer somehow to short*

// ...

}
else(...)
{
// Change the type of the pointer somehow to char*

// ...

}

// Read back whatever I get

DWORD dwReadBack = pArray[0];


If it is impossible, and that would be my guess, then how do this in a 'really neat' way. I already have solutions but they all suck grace.

Lorenz

[edited by - sprinter_trueno on May 29, 2003 2:58:06 PM]

Share this post


Link to post
Share on other sites
If you have void *pvArray, you cannot change what type pvArray is, but you can change how you access it.

If you want to access it as another type just use
(char *)pvArray
(short *)pvArray
(long *)pvArray

Get it?


[edited by - BeerNutts on May 29, 2003 3:04:10 PM]

Share this post


Link to post
Share on other sites

  

char Array[4];
void* pArray = (void*)Array;
// Somewhere else

if(...)
{
// NOTE: This will not just get you the first element

// of the array. It will get you ALL 4 elements.

int iReadBack = *(int*)pArray;
}
else if(...)
{
// This will get you 2 elements

short iReadBack = *(short*)pArray;
}
else(...)
{
// This will get you one.

char cReadBack = *(char*)pArray;
}


The reason for the different size retrievals is that the array was declasred as a 4 element char array. Each char is 1 byte, so the array size is 4 bytes.

an int is 4 bytes, so by casting to an int you will be retirieving a value 4 bytes long, therefor extracting all 4 bytes of the array when derefrencing the pointer. To better understand it you have to take into account what beernuts said: "you cannot change what type pvArray is, but you can change how you access it"

say for example I have a variable

DWORD var = 0xFFFFFFFF;

that variable is chock-a-block. The value cannot have a higher number, if you add one it will roll back to 0.

If you just want to extract 1 byte from that, you can get a char pointer and point it to the variable, then when you dereference teh char pointer it will get you 1 bytes worth of data. a short will get you 2 bytes, etc...

char* pCharVar = (char*)&var;

int iOneByteValue = *pCharVar;

If I''m not mistaken, iOneByteValue will have the value 0xFF inside it. One full byte, (255).


:::: [ Triple Buffer V2.0 ] ::::

Share this post


Link to post
Share on other sites
quote:
Original post by sprinter_trueno
Well, since you pointed out my inexperience, could you also provide me with an example ?

Would be very appreciated.


I apologize, I was having a bad morning.

Share this post


Link to post
Share on other sites
The anonymous poster presented a typesafe way of doing this through boost::any, I don''t see why you wouldn''t use that.

Share this post


Link to post
Share on other sites
quote:

To better understand it you have to take into account what beernuts said: "you cannot change what type pvArray is, but you can change how you access it"


If there really isn't a way to do so then this is actually the answer to my question.

It's just that putting the 'if else' so close to the array access makes my code highly performance inefficient. To work around this I need to put my complete overhead (which is quite alot and for every case of course the same) into the 'if else' construct (ugly, inflexible).
Changing the pointers type at runtime would have been a neat way but c++ seems to have a weakness regarding this.

Thanks for all the comments on this.

Lorenz

[edited by - sprinter_trueno on May 30, 2003 1:35:16 AM]

Share this post


Link to post
Share on other sites
I seriously doubt you need if/else statements. Tell us the context this code will be used in, as I''m sure we can come up with a good way of doing it.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
I''d love to agree.
Short description: (GB emu) I convert the sprite and tile data of the GB (which is 2-bit) into either 16 or 32 bit format and write the pixels into a directdraw surface.

There are 256 tiles stored in the array and each tile is 8x8 pixels in size.

After a lock of the surface the pointer to the surface is void* and you make the cast by the display mode the user chose. 16 bit or 32.


for (Tile = 0; Tile < 256; Tile++)
{
...
...

for (Line = 0; Line < 8; Line++)
{
...
...

for (Row = 0; Row < 8; Row++)
{
Color = ....... ;
// The next line is my problem

pTileSurface[...] = PixelLookUpTable[Color];

...
...

} // END OF ROW


...
...

} // END OF LINE


...
...

} // END OF TILE TABLE




pTileSurface varies between two types. Using ''if'' performance efficiently I have to place the whole loop thing once for 16 bit and once for 32 bit since I need two different pointers.

Is there another way ?

Share this post


Link to post
Share on other sites
I assume you mean something like this?

((WORD*)pTileSurface)[(Y * TilePitch) + (X << BytesPerPixel)] = Color;
//vs

((DWORD*)pTileSurface)[(Y * TilePitch) + (X << BytesPerPixel)] = Color;

There''s no good way to reduce those literal equations. The compiler assigns 16-bit values through the CPU''s 16-bit move instruction, and 32-bit data through the 32-bit instruction. They''re different instructions that are being called so you can''t alter that at run-time (unless you use self-modifying code, but I''ve never tried that).

However, aren''t you just creating these tiles at startup, not at runtime? If so then you are being absurd in trying to optimize this through the elimination of a single if statement. Either write two versions of the loop or put the if statement in the inner-most one, it does not matter for simple initialization code, unless you are running the emulator on ENIAC.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites