C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old February 13th, 2003, 12:52 PM
SLSTEK@Work SLSTEK@Work is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Feb 2003
Posts: 2 SLSTEK@Work User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Need a C equivalent for C++ dynamic_cast

Looking for a way in C to recast a pointer to a different data type or structure dynamically like dynamic_cast in C++. Can this be done in C with void * or something similar??

Also can an array of C pointers have different types assigned by recasting somehow? If so how to do in C?

I basically want a pointer to behave as a pointer to a different data type or different structure actually depending on the value of a parameter. This will allow me to read a buffer region differently depending on the contents and its structure.

Thanks!

Reply With Quote
  #2  
Old February 13th, 2003, 01:54 PM
dwise1_aol's Avatar
dwise1_aol dwise1_aol is offline
Contributing User
Dev Shed God 2nd Plane (6000 - 6499 posts)
 
Join Date: Jan 2003
Location: USA
Posts: 6,134 dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 2 Weeks 3 Days 20 h 49 m 18 sec
Reputation Power: 1974
Very simple: use type-casting.

If you type-cast a variable to another data type, then the value will be retained but will now be in the now type's format; eg:

unsigned char Byte = 0x80; // one byte long
int i = (int)Byte; // now two bytes long

float fl = 1.5f;
int trunct = (int)fl; // has been truncated to a value of 1


To keep from messing up the size of the data, use pointers and typecast from one type of pointer to another.

For example, I recently experiment with creating an unsigned long integer and then listing the value of each individual byte:

Code:
    unsigned long ulIP;
    unsigned char *cp;
    char address[80];

    cp = (unsigned char*)&ulIP;

    // convert dotted-decimal to network-order address
    ulIP = inet_addr(address);
    printf("%s --> %d.%d.%d.%d\n",address,*cp,*(cp+1),*(cp+2),*(cp+3));


I took the address of ulIP, which would be an (unsigned long*) and typecast it as (unsigned char*) in order to assign it to a variable of that type.

You can also do something like:
int i = *((int*)&some_long_int);

Hope that helps.

Reply With Quote
  #3  
Old February 13th, 2003, 03:10 PM
dwise1_aol's Avatar
dwise1_aol dwise1_aol is offline
Contributing User
Dev Shed God 2nd Plane (6000 - 6499 posts)
 
Join Date: Jan 2003
Location: USA
Posts: 6,134 dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 2 Weeks 3 Days 20 h 49 m 18 sec
Reputation Power: 1974
My C++ work was just before the re-standardization a half-decade or so ago, so I wasn't very familiar with dynamic casting.

Looking it up on-line, it appears to be very C++-specific in that it depends on run-time type identification and works on classes derived from the same base class. C has neither feature.

My guess would be that you will need to write a different function for each struct type and test explicitly which one to call.

A real-life example might be the sockaddr structure in sockets programming. struct sockaddr is just a generic struct that has an ID (sa_family) as its first element and an array of bytes to fill the remainder. Then for TCP/IP you use a struct sockaddr_in which has the same initial ID field, which tags the address structure as being of a specific type. All sockets functions that take an address are written to take a struct sockaddr pointer, so you write the function call to cast your pointer to a sockaddr_in as a (struct sockaddr*).

Hope that helps. If it doesn't, then perhaps a short example of what you're trying to do would help us help you better.

Reply With Quote
  #4  
Old February 13th, 2003, 03:12 PM
SLSTEK@Work SLSTEK@Work is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Feb 2003
Posts: 2 SLSTEK@Work User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Thanks dwise, but not exactly what I want to do.

I want something dynamic like this:

Code:
typedef struct {float a[1]; float b;} MY_STRUCT1;
typedef struct {float a[2]; float b;} MY_STRUCT2;

float databuffer [1000];

void *variableStructPtr;

if (numElementsInA == 1)
    variableStructPtr = (MY_STRUCT1 *) &(databuffer[0]);
else
    variableStructPtr = (MY_STRUCT2 *) &(databuffer[0]);
.
.
.

Then access the structure components variableStructPtr->a[i] and
variableStructPtr->b to extract data from a buffer in different ways depending on what is in the buffer, but I want to do it with a single variable pointer...

In other words, I want to change the behavior and the type of the pointer itself. Can this be done in C by some means (maybe something cast to a "void" pointer and then cast the "void" pointer into something else)??

Last edited by SLSTEK@Work : February 13th, 2003 at 03:19 PM.

Reply With Quote
  #5  
Old February 13th, 2003, 05:59 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Dev Shed God 9th Plane (9000 - 9499 posts)
 
Join Date: Nov 2001
Location: Woodland Hills, Los Angeles County, California, USA
Posts: 9,387 Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 4 Weeks 1 Day 21 h 39 m 3 sec
Reputation Power: 4080
Quote:
Originally posted by SLSTEK@Work
In other words, I want to change the behavior and the type of the pointer itself. Can this be done in C by some means (maybe something cast to a "void" pointer and then cast the "void" pointer into something else)??


Yep, that would be one way to do it. All you have to do is pass some kind of int value or something like that, so that the other end knows how to typecast the void pointer back to the proper struct.

If you look at the sockets API, you'll notice that the socket functions accept a structure of type sockaddr and other extra parameters. However, for actual coding, the programmer usually uses a sockaddr_in or sockaddr_in6 or whatever. When passing the structure to the socket functions, the programmer typecasts the variable to type sockaddr so the function will accept it.

Now if you look at the definitions of the structures, the first three or four members of struct sockaddr, sockaddr_in, sockaddr_in6 etc. are the same name and type. So the function can look at the sockaddr.ss_family field and determine the actual type of pointer that this should be. Then it typecasts the pointer back accordingly and accesses the remaining members that are unique to that structure type. This way, you only have one function that accepts a sockaddr type, instead of defining multiple functions that do the same thing, but accepting sockaddr_in, sockaddr_in6 etc.
http://www.experts-exchange.com/Pro...Q_20337039.html

Hope this helps!

Last edited by Scorpions4ever : February 13th, 2003 at 06:04 PM.

Reply With Quote
  #6  
Old February 13th, 2003, 07:08 PM
SLSTEK SLSTEK is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Feb 2003
Posts: 2 SLSTEK User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Ahhhhh -- Nice info and link Scorpions4ever and very similar to what I am looking to try to do; will have to examine and unravel that sockets API and see what they are doing inside; probably a switch + case select probably to recast according to the common "ss_family" structure member...

The problem I was/am having in trying to use a generic void * type definition and then a recast, was that the a compile time error indicated incorrect void type for the expression on the selection operator, but for a global parameter definition. Will experiment with a local function variable with internal recasting within each case selection and see what happens.

Thanks a bunch guys!

Reply With Quote
  #7  
Old February 14th, 2003, 03:53 PM
3dfxMM 3dfxMM is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2002
Posts: 272 3dfxMM User rank is Sergeant (500 - 2000 Reputation Level)3dfxMM User rank is Sergeant (500 - 2000 Reputation Level)3dfxMM User rank is Sergeant (500 - 2000 Reputation Level)3dfxMM User rank is Sergeant (500 - 2000 Reputation Level)3dfxMM User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 6 Days 17 h 57 m 24 sec
Reputation Power: 17
You could also read up on the use of unions in almost any C book.

Reply With Quote
  #8  
Old February 14th, 2003, 10:15 PM
SLSTEK SLSTEK is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Feb 2003
Posts: 2 SLSTEK User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Yes -- unions is definitely a nice feature for variable access and use for other things (good sections in both K&R new text and H&S's C: A Reference Manual), but want to try to get the variable pointer method to work with casting, but not exactly the way I had hoped. I can also access the data via brute force with ++ operators and looping, which would be faster most likely too. I use unions to access data optionally as unsigned, integer, or floats in some cases when buffers contain different data types and is very nice too, plus do lots of casting with dynamic memory with malloc, realloc, etc. I was just wanting to generalize it with a single pointer with a single name and use selections operators and see if performance is adequate.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > Need a C equivalent for C++ dynamic_cast

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap