c like structure in Perl

A

adarsh.hrbr

Hi all,

I have written a socket program whose Client is in Perl and the
Server is in C. To some extent I was successful in obtaining the data
and printing the same. But my server (UDP ) has some structures . The
data pertaining to these structures are to be communicated from the
Perl client. I thought using hash in Perl could be to solution, but
what I am sceptical about is; will I be able to typecast the same in c
to obtain the data?

Below is a structure in c which I want to type cast. Can somebody
suggest a method to define this in Perl so that I can typecaste the
same in my Server to obtain the data.

typedef struct {

uint8 Reserved;
uint32 ipaddr;
uint32 netmask;
uint16 command;

} sample;

uint - unsigned int type - 8,16 and 32 bytes - in length
 
J

Josef Moellers

Hi all,

I have written a socket program whose Client is in Perl and the
Server is in C. To some extent I was successful in obtaining the data
and printing the same. But my server (UDP ) has some structures . The
data pertaining to these structures are to be communicated from the
Perl client. I thought using hash in Perl could be to solution, but
what I am sceptical about is; will I be able to typecast the same in c
to obtain the data?

Below is a structure in c which I want to type cast. Can somebody
suggest a method to define this in Perl so that I can typecaste the
same in my Server to obtain the data.

typedef struct {

uint8 Reserved;
uint32 ipaddr;
uint32 netmask;
uint16 command;

} sample;

uint - unsigned int type - 8,16 and 32 bytes - in length

The only thing I can come up is pack/unpack.
 
M

Mirco Wahab

Thus spoke (e-mail address removed) (on 2006-10-24 06:57):
Below is a structure in c which I want to type cast. Can somebody
suggest a method to define this in Perl so that I can typecaste the
same in my Server to obtain the data.

typedef struct {

uint8 Reserved;
uint32 ipaddr;
uint32 netmask;
uint16 command;

} sample;

As Josef said, you have to build a 'unpack'
format and unpack the struct parts into
variables. I did this sometimes and your
example seems easy enough to make some
example of it:

...
sample s; /* your sample from above */
char* c;
printf("my $c_strct = read_record();\nmy $fmt = \"");
printf("C"); /* Reserved */
for(c=(char*)&s.Reserved+1; c<(char*)&s.ipaddr; c++) printf("x");
printf("L"); /* ipaddr */
for(c=(char*)&s.ipaddr+4; c<(char*)&s.netmask; c++) printf("x");
printf("L"); /* netmask */
for(c=(char*)&s.netmask+4; c<(char*)&s.command; c++) printf("x");
printf("S"); /* command */
for(c=(char*)&s.command+2; c<(char*)&s+sizeof(s); c++) printf("x");
printf("\";\nmy ($Reserved, $ipaddr, $netmask, $command) = unpack($fmt, $c_strct);\n");
...

(I hope I got this right and made not too much mistakes here ;-)

If you have 'encoded' your ip or netmask in some way (sequence of 4 IPV4-bytes)
you have to decode that $ipaddr (long) by unpacking it again (unpack "CCCC", $ipaddr)
to get the 4 numbers out, same with netmask.

But I'm sure there are some Modules for this too -- but you see the picture?

Regards

Mirco
 
I

Ingo Menger

Hi all,

I have written a socket program whose Client is in Perl and the
Server is in C. To some extent I was successful in obtaining the data
and printing the same. But my server (UDP ) has some structures . The
data pertaining to these structures are to be communicated from the
Perl client. I thought using hash in Perl could be to solution, but
what I am sceptical about is; will I be able to typecast the same in c
to obtain the data?

Below is a structure in c which I want to type cast. Can somebody
suggest a method to define this in Perl so that I can typecaste the
same in my Server to obtain the data.

typedef struct {

uint8 Reserved;
uint32 ipaddr;
uint32 netmask;
uint16 command;

} sample;

uint - unsigned int type - 8,16 and 32 bytes - in length

perldoc -f pack

Note that between any two fields of the struct the C compiler may have
inserted some padding.
 
D

Dr.Ruud

(e-mail address removed) schreef:
Below is a structure in c which I want to type cast. Can somebody
suggest a method to define this in Perl so that I can typecaste the
same in my Server to obtain the data.

typedef struct {

uint8 Reserved;
uint32 ipaddr;
uint32 netmask;
uint16 command;

} sample;

uint - unsigned int type - 8,16 and 32 bytes - in length

The sizeof(sample) doesn't need to be 11. If not, use 'offsetof(s,m)',
or subtract pointers, to find out where the members are in the struct.
See also #pragma pack().
 
P

Peter J. Holzer

[I'm following up to Dr.Ruud because I want to expand his good advice,
but it is really an answer to the OP - so "you" in the following refers
to (e-mail address removed)]

(e-mail address removed) schreef:

ITYM bits, not bytes.

The sizeof(sample) doesn't need to be 11.

Indeed it is unlikely to be 11. Almost every C compiler will insert
three padding bytes between "Reserved" and "ipaddr" to get the latter on
a 32 bit boundary (and another 2 bytes at the end for the same reason).
But some compilers may pad only to 16 bits or not at all.

Avoid the use of structs in I/O. It looks simple at first, but isn't -
you need to carefully lay out your structs to avoid padding issues and
then you still have to deal with endianness and other representation
issues - better to define your protocol as a byte stream in the first
place.

Since you are probably stuck with the server, use Dr. Ruud's
advice:
If not, use 'offsetof(s,m)', or subtract pointers, to find out where
the members are in the struct. See also #pragma pack().

to document the current behaviour and make it mandatory: I.e. if you
find that the struct really looks like this (which I would guess for
modern C-compilers):

typedef struct {

uint8 Reserved;
uint8 Reserved1;
uint8 Reserved2;
uint8 Reserved3;
uint32 ipaddr;
uint32 netmask;
uint16 command;
uint8 Reserved4;
uint8 Reserved5;

} sample;

define that this is the intended format: 4 reserved bytes, followed by 4
bytes ipaddr, 4 bytes netmask, 2 bytes of command and another 2
reserved bytes. Also you probably must standardize on some byte order
(preferrably network byte order (big endian) since you already have an
ip-address and a netmask in there).

Then - and only then, not before - use pack/unpack to create/parse the
format you have defined.

hp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top