mte01
asked on
Converting structure object to char*
Hey experts,
I took the following as a part of an open source code, but it doesn't seem to be working properly:
#define RTP_HDR_SZ 12
typedef struct {
unsigned int version:2; /* protocol version */
unsigned int p:1; /* padding flag */
unsigned int x:1; /* header extension flag */
unsigned int cc:4; /* CSRC count */
unsigned int m:1; /* marker bit */
unsigned int pt:7; /* payload type */
unsigned int seq:16; /* sequence number */
unsigned int ts:32; /* timestamp */
unsigned int ssrc:32; /* synchronization source */
} rtp_hdr_t;
rtphdr.version = 2;
rtphdr.p = 0;
rtphdr.x = 0;
rtphdr.cc = 0;
rtphdr.m = 0;
rtphdr.pt = 24;
rtphdr.seq = (unsigned int)(3);
rtphdr.ts = (unsigned int)time(0);
rtphdr.ssrc = 1094;
char* rtp_header = new char[RTP_HDR_SZ];
memcpy(rtp_header,&rtphdr, RTP_HDR_SZ);
for(i=0;i<RTP_HDR_SZ;i++)
{
cout<<rtp_header[i]<<" ";
}
cout<<endl;
when I try to print the characters of rtp_header to see if it was actually filled by the contents of rtphdr, they turn out to be some weird characters (and not corresponding to that data that I filled the structure object with...any idea where the problem is??
I took the following as a part of an open source code, but it doesn't seem to be working properly:
#define RTP_HDR_SZ 12
typedef struct {
unsigned int version:2; /* protocol version */
unsigned int p:1; /* padding flag */
unsigned int x:1; /* header extension flag */
unsigned int cc:4; /* CSRC count */
unsigned int m:1; /* marker bit */
unsigned int pt:7; /* payload type */
unsigned int seq:16; /* sequence number */
unsigned int ts:32; /* timestamp */
unsigned int ssrc:32; /* synchronization source */
} rtp_hdr_t;
rtphdr.version = 2;
rtphdr.p = 0;
rtphdr.x = 0;
rtphdr.cc = 0;
rtphdr.m = 0;
rtphdr.pt = 24;
rtphdr.seq = (unsigned int)(3);
rtphdr.ts = (unsigned int)time(0);
rtphdr.ssrc = 1094;
char* rtp_header = new char[RTP_HDR_SZ];
memcpy(rtp_header,&rtphdr,
for(i=0;i<RTP_HDR_SZ;i++)
{
cout<<rtp_header[i]<<" ";
}
cout<<endl;
when I try to print the characters of rtp_header to see if it was actually filled by the contents of rtphdr, they turn out to be some weird characters (and not corresponding to that data that I filled the structure object with...any idea where the problem is??
Hi mte01,
Data has been packed into bit fields and you are printing out chars!! ... get a dump in hex and compare with the information you stored.
Cheers!
Sunnycoder
Data has been packed into bit fields and you are printing out chars!! ... get a dump in hex and compare with the information you stored.
Cheers!
Sunnycoder
ASKER
>>Kdo
Yes, I know that, but I guessed there should be something that I could recognize from the printed characters (related to the inputted data)...anyway, what I am doing is that I am sending this char* over a simulated udp channel, and then I am receiving it at the client side...any help on how to extract from the received char* the sequence number for example??
Yes, I know that, but I guessed there should be something that I could recognize from the printed characters (related to the inputted data)...anyway, what I am doing is that I am sending this char* over a simulated udp channel, and then I am receiving it at the client side...any help on how to extract from the received char* the sequence number for example??
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
>>The receiving end is going to have to know the format of the data so that it can unpack it
Yes, I know
>>Include your structure there and as a debugging test, print the fields to make sure that you're getting what you expect
Thats what I am asking you to help me in, do I also use memcpy to the char* object to an rtp_hdr_t object or what??
Yes, I know
>>Include your structure there and as a debugging test, print the fields to make sure that you're getting what you expect
Thats what I am asking you to help me in, do I also use memcpy to the char* object to an rtp_hdr_t object or what??
Hi mte01,
That's probably the easiest, though you can explicitly just recast the items on the fly.
Kent
That's probably the easiest, though you can explicitly just recast the items on the fly.
Kent
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
This thing is going to drive me crazy:)....I did the following:
rtp_hdr_t rtphdr;
rtp_hdr_t* rtphdr2 = new rtp_hdr_t[RTP_HDR_SZ];
rtphdr.version = 0;
rtphdr.p = 0;
rtphdr.x = 0;
rtphdr.cc = 0;
rtphdr.m = 0;
rtphdr.pt = 0;
rtphdr.seq = (unsigned int)(12);
rtphdr.ts = (unsigned int)(0);
rtphdr.ssrc = 0;
char* rtp_header = new char[RTP_HDR_SZ];
memcpy(rtp_header,&rtphdr, RTP_HDR_SZ);
memcpy(rtphdr2,&rtp_header , RTP_HDR_SZ);
cout<<rtphdr2->seq<<endl;
I am getting an output of 73!! any idea why??
rtp_hdr_t rtphdr;
rtp_hdr_t* rtphdr2 = new rtp_hdr_t[RTP_HDR_SZ];
rtphdr.version = 0;
rtphdr.p = 0;
rtphdr.x = 0;
rtphdr.cc = 0;
rtphdr.m = 0;
rtphdr.pt = 0;
rtphdr.seq = (unsigned int)(12);
rtphdr.ts = (unsigned int)(0);
rtphdr.ssrc = 0;
char* rtp_header = new char[RTP_HDR_SZ];
memcpy(rtp_header,&rtphdr,
memcpy(rtphdr2,&rtp_header
cout<<rtphdr2->seq<<endl;
I am getting an output of 73!! any idea why??
Hi sunnycoder,
What hardware and operating systems are you using on both ends?
Kent
What hardware and operating systems are you using on both ends?
Kent
ASKER
>>Kdo
Forget the client now...now I am just testing as you see only at the server....I am converting from structure to char* and then back to structure & I am getting different output; I am just testing right now the code of the server on a windows xp pc (AMD Athlon processor) using MS Visual C++ 6.0
Forget the client now...now I am just testing as you see only at the server....I am converting from structure to char* and then back to structure & I am getting different output; I am just testing right now the code of the server on a windows xp pc (AMD Athlon processor) using MS Visual C++ 6.0
Hi mte01,
The bit signatures of 12 and 73 are completely different (1100 vs 1001001) so I'd like to know what is being displayed. :)
Can you run your test again setting seq to 0. Then run it again with seq = 1. I'd like to see what the results are.
Kent
The bit signatures of 12 and 73 are completely different (1100 vs 1001001) so I'd like to know what is being displayed. :)
Can you run your test again setting seq to 0. Then run it again with seq = 1. I'd like to see what the results are.
Kent
ASKER
>>Kdo
It's always 73...:D....and the timestamp is always 500.....try it on your pc..(the structure is in the question above)....
It's always 73...:D....and the timestamp is always 500.....try it on your pc..(the structure is in the question above)....
Hi mte01,
That's very telling. :) It suggests that what you're displaying is NOT the field that you set!
So..... Let's experiment and see if it's correct in the original structure. Right before the cout statement, insert this:
cout << rtphdr.seq << endl;
Kent
That's very telling. :) It suggests that what you're displaying is NOT the field that you set!
So..... Let's experiment and see if it's correct in the original structure. Right before the cout statement, insert this:
cout << rtphdr.seq << endl;
Kent
ASKER
>>memcpy(rtp_header,&rtphd r, RTP_HDR_SZ);
That was the problem....It should be: memcpy(&rtp_header,&rtphdr , RTP_HDR_SZ);
I hate C & C++ because of these things!!.....thanks for your help guys!!
That was the problem....It should be: memcpy(&rtp_header,&rtphdr
I hate C & C++ because of these things!!.....thanks for your help guys!!
Hi mte01,
Don't think so. rtp_header is a pointer so passing the pointer should be corrent. rtphdr is a structure so you must pass its pointer by prepending the '&'
By the way, you're using C++ syntax. I've converted to C and run the following code. Both lines yield 12, 12.
rtp_hdr_t rtphdr;
main ()
{
char* rtp_header;
rtphdr.version = 2;
rtphdr.p = 0;
rtphdr.x = 0;
rtphdr.cc = 0;
rtphdr.m = 0;
rtphdr.pt = 24;
rtphdr.seq = (unsigned int)(12);
rtphdr.ts = (unsigned int)time(0);
rtphdr.ssrc = 1094;
rtp_header = (char *)malloc (RTP_HDR_SZ);
memcpy(rtp_header,&rtphdr, RTP_HDR_SZ);
fprintf (stdout, " %d, %d\n", RTP_HDR_SZ, sizeof (rtp_hdr_t));
fprintf (stdout, " %d, %d\n", rtphdr.seq, ((rtp_hdr_t *)rtp_header)->seq);
Kent
Don't think so. rtp_header is a pointer so passing the pointer should be corrent. rtphdr is a structure so you must pass its pointer by prepending the '&'
By the way, you're using C++ syntax. I've converted to C and run the following code. Both lines yield 12, 12.
rtp_hdr_t rtphdr;
main ()
{
char* rtp_header;
rtphdr.version = 2;
rtphdr.p = 0;
rtphdr.x = 0;
rtphdr.cc = 0;
rtphdr.m = 0;
rtphdr.pt = 24;
rtphdr.seq = (unsigned int)(12);
rtphdr.ts = (unsigned int)time(0);
rtphdr.ssrc = 1094;
rtp_header = (char *)malloc (RTP_HDR_SZ);
memcpy(rtp_header,&rtphdr,
fprintf (stdout, " %d, %d\n", RTP_HDR_SZ, sizeof (rtp_hdr_t));
fprintf (stdout, " %d, %d\n", rtphdr.seq, ((rtp_hdr_t *)rtp_header)->seq);
Kent
ASKER
>>Kdo
Yes, apparently in C++ it needs this reference to the whole char* array (It is working now with me)......and by the way sorry for asking the question here in the C TA
Yes, apparently in C++ it needs this reference to the whole char* array (It is working now with me)......and by the way sorry for asking the question here in the C TA
Hi mte01,
> sorry for asking the question here in the C TA
That's fine. Most of the C experts are also fluent with C++. :)
Kent
> sorry for asking the question here in the C TA
That's fine. Most of the C experts are also fluent with C++. :)
Kent
Your structure contains binary values that are packed, often several fields to a byte. When you display the structure by sending it to cout, the C libraries simply copy the bytes. The do not convert the data as you seem to want.
You're going to have to format the output yourself. Here's a start. Just add the fields that you want displayed.
printf (" Version=%d, pad=%d, extension=%d\n", rtphdr.version, rtphdr.p, rtphdr.x);
Good Luck!
Kent