[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
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
Medium Priority
?
256 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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

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 1500 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

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…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
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.
Suggested Courses

867 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