Solved

C++ Question buffer[x](char type) to return data to a interger or reference point of buffer to a another struct then get variable from the struct??

Posted on 2004-08-30
13
230 Views
Last Modified: 2010-04-01
Hi,

  I would like to know this specific typecast conversion which I not sure how to procede.

struct MyStruct
{
    unsigned short A;
    long B;
    integer C;
    char D;
}

char* Buffer;
MyStruct *MyS;

Let'ss assume that Buffer as been assigned and all that.

Let's also assume that Buffer[2] to Buffer[5] has the B value of 123456

Ok I need to do smething like this.

MyS = (MyStruct *) Buffer;

I suppose that MyS is now at the exact same address has of Buffer concerning the first byte.
So then Mys.B should be equal to 123456 but it does not seam to work, mine is always 0

Anyway Help about this typecast or whatever other term we could give it;

Basily what I need is that one struct shadow the Buffer at whatever possible because I could and will start MyStruct
at any position in the Buffer and would like to et the data in the pointer through the "avatar" MyS.B for example unless
you can get you data as for example a long type from a buffer that have a array of char from whatever position??

One more thing is that I want to get this info into a normal variable like long Test = MyS.B which should be equal to
123456 for example and not zero.

Thank you

 
0
Comment
Question by:Dogofwars
  • 3
  • 3
  • 3
  • +2
13 Comments
 
LVL 55

Expert Comment

by:Jaime Olivares
Comment Utility
Assumming your buffermatch exactly with entire buffer:

memcpy(MyS, Buffer, sizeof(MyS));
0
 
LVL 55

Expert Comment

by:Jaime Olivares
Comment Utility
Also you can assign individual member as you mentioned:

memcpy(&MyS.B, Buffer+2,  sizeof(MyS.B));
0
 
LVL 55

Expert Comment

by:Jaime Olivares
Comment Utility
Sorry, have not explained that MyS is not a pointer, in my examples. Also, if you are reading from a bigger buffer, you will need some kind of "offset" variable. So you can move (or point) data from "Buffer+Offset" to the struct, then you can advance Offset variable, Buffer remains untouched.
Maybe you can post some code to help better.
0
 

Author Comment

by:Dogofwars
Comment Utility
MyS is only a reference pointer it's not a pointer with a memory space of it's own that you alloc or free.
MyS is simply shadowing Buffer.

It's like this MyS pointer is = to Buffer pointer so basicly the address of both are identical.
After that from MyS I would like to transfert MyS.B to long Test;

Example

MyS = (MyStruct*) Buffer[x]; // X can be any possition in the char arrays
long Test = MyS.B; //(which is of type long)

So basicly all I do is to get the data from Buffer[x] to Test(the variable) in a more fine way. I will not
trasfert from one buffer to another since it does not need all the data and it's just wasting the time
of the processor.

Thank you
0
 
LVL 3

Accepted Solution

by:
Indrawati earned 500 total points
Comment Utility
Hi

Just want to point something to you:
1. Buffer is of char* type, so Buffer[x] will refer to the xth character, not the xth MyStruct. To refer to the xth MyStruct in the buffer, you may have to do something like:

MyS = reinterpret_cast<MyStruct*>(&Buffer[x*sizeof(MyStruct)]);

2. Note the & sign in front of Buffer in the above code. It is required to get the address, not the element at Buffer[x*sizeof(MyStruct)].

3. If Buffer is a shadowing buffer which is not malloc or freed, make sure that the variables pointed to by Buffer is not out of scope when you perform the Buffer[x*sizeof(MyStruct)].

I tried this on my compiler, and it works OK:

      MyStruct A[5];
      char *buff = reinterpret_cast<char*>(A);

      A[1].B = 123456;
      MyStruct *tmp = reinterpret_cast<MyStruct*>(&buff[sizeof(MyStruct)*1]);
      cout << tmp->B;
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Your approach should just work fine, and it does:

#include <iostream>
using namespace std;

struct MyStruct
{
   unsigned short A;
   long B;
   int C;
   char D;
};

int main () {

    MyStruct ms;
    char* pc = (char*) &ms;

    ms.B = 123456;
    cout << "ms.B is being set to " << ms.B << endl;

    //...

    MyStruct* pms = (MyStruct*) pc;
    cout << "...and pms->B actually reads " << pms->B << endl;

    return 0;
}

Output:

ms.B is being set to 123456
...and pms->B actually reads 123456
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:Dogofwars
Comment Utility
My question was not that complex to understand but let's try it again, or maybe I don't understand your answer ;)


struct MyStruct
{
    unsigned short A;
    long B;
    integer C;
    char D;
}

char *Buffer; //Pretend it's allocate and the actual data is already in forget about the whole thing that you need to
                    // do this make this append.
MyStruct *MyS = NULL; //This is not a pointer that wil hold the data itself but will only reference to the position
                                  // of Buffer[x]
long Test;//Well no need to explain ;)

If I apply what you say then:

MyS = reinterpret_cast<MyStruct*>(&buff[0]);
Test = MyS.B;

Then:

Test would be equal to 123456 if it would 123456 in th Buffer in the relative position of MyStruct.B??




 





0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Yes. E.g. that's what your DVD player software does - it reads raw data into a buffer, casts it to a 'MPEG_PACKET*' (ok, that struct name I made up, but as it serves only for illustration purposes) and checks the stream id of that packet (and that one I am not making up at all :o)
0
 
LVL 3

Expert Comment

by:Indrawati
Comment Utility
If you change the last two lines to this code:

MyS = reinterpret_cast<MyStruct*>(&buff[0*sizeof(MyStruct)]);
Test = MyS->B;

Then you'll get 123456, yes.
0
 
LVL 3

Expert Comment

by:Indrawati
Comment Utility
Just to add, buff is of char* type, and the size of a char is one byte, while the size of MyStruct larger than byte. So to get the correct offset into the buff array, you have to use simple arithmetic using sizeof(MyStruct) which produces the size of MyStruct.

e.g.
MyStruct MS[5];
char *buff = reinterpret_cast<char*>(MS);

the first element in MS is in the address: &buff[0*sizeof(MyStruct)]
the second element in MS is in the address: &buff[1*sizeof(MyStruct)]
the third element in MS is in the address: &buff[2*sizeof(MyStruct)]
and so on, and so on...
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
Dogofwars,
As jkr stated, your original approach should work as-is.

If you're not getting the right results, then more then likely, there is something else wrong with the code.

Can you post the rest of your code?
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Yup, that's pretty much what I wanted to add also.
0
 

Author Comment

by:Dogofwars
Comment Utility
MyS = reinterpret_cast<MyStruct*>(&buff[x]); is the correct answer and was what I was looking for.

I need to get a avatar of my buffer that is a array of char but with a array of char it's more trouble than needed,
so I needed a solution to use a structure instead but it needed to point to the location of the buffer starting
at whatever position in the array that I saw fit. Could not have found it myselft without the help of Indrawati
which had a complet answer. My approach was correct as jkr mention but only at the base address and that was
my problem. Since I needed to have 4 pointers pointing at the same buffer but at any location which I specified
to point at any location only reinterpret_cast<MyStruct*>(&buff[x]) was the answer any other attemp was only working if I needed to point at the base but I needed to have it at any location.

Thank you

P.S. Admin If you think otherwise you can reatribute the score unfortunatly my code is quiet conplex and I don't
really want to share it. Thank for all participant.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now