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
232 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
ID: 11937041
Assumming your buffermatch exactly with entire buffer:

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

Expert Comment

by:Jaime Olivares
ID: 11937046
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
ID: 11937187
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
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 

Author Comment

by:Dogofwars
ID: 11937358
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
ID: 11937525
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
ID: 11937571
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
 

Author Comment

by:Dogofwars
ID: 11937599
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
ID: 11937619
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
ID: 11937624
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
ID: 11937659
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
ID: 11937809
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
ID: 11937949
Yup, that's pretty much what I wanted to add also.
0
 

Author Comment

by:Dogofwars
ID: 11938207
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

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

813 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

10 Experts available now in Live!

Get 1:1 Help Now