LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   In perl how to send numeric+string data into message queues? (https://www.linuxquestions.org/questions/linux-newbie-8/in-perl-how-to-send-numeric-string-data-into-message-queues-4175473298/)

Shahid nx 08-14-2013 12:18 AM

In perl how to send numeric+string data into message queues?
 
Hi,
I need to write a IPC between c++ process and perl module using message queues.
My c++ program is reading queue with following structure.
Code:

struct HealthCheckMsg
{
  int moduleId;
  EnumHealthCheckCode healthCheckCode;
  EnumHealthCheckLevel healthCheckLevel;
  char processName[101];

};

But in perl module i m not able to send data in queue like above format.
In perl i m trying to send data in this way

Code:

my      $OamMsgType=1;
my      $moduleId=2006;
my      $healthCheckCode=0;
my      $healthCheckLevel=0;
my      $processName="PRBT_Bhutan";
#my      $HCMessage=$moduleId.$healthCheckCode.$healthCheckLevel.$processName;
#msgsnd($WrHCQId,pack("l!a*",$OamMsgType,$HCMessage), 0)

c++ program is printing th out put as
moduleId 909127730
healthCheckCode 1380986928
healthCheckLevel 1113543746
processName hutan.

And also i observed that c++ program is treating first three values as string instead of numeric.
I m very new to perl so don't have much idea. please any body can help me out..

j-ray 08-14-2013 02:20 AM

Maybe this comes in handy?

http://search.cpan.org/~rjbs/perl-5....lass/Struct.pm

With this you can probably create a struct like in c++, asssign the values and send them instead of a string? I'm just guessing...

Cheers,j

jpollard 08-14-2013 12:32 PM

Quote:

Originally Posted by j-ray (Post 5008975)
Maybe this comes in handy?

http://search.cpan.org/~rjbs/perl-5....lass/Struct.pm

With this you can probably create a struct like in c++, asssign the values and send them instead of a string? I'm just guessing...

Cheers,j

I believe that is a Win32 structure, not a C++ structure.

What I think you are looking for is the pack and unpack functions. These will translate to/from a binary sequence of data into a buffer (as represented by a string). Once the structure is complete you should be able to send the string buffer used to the C++.

A short reference to reading a C structure is at http://www.perlmonks.org/?node_id=50023
Think of this as just a VERY brief example.

A more complete addressing is at http://search.cpan.org/~mhx/Convert-...rt/Binary/C.pm
This is more likely what you need as the structures used by C++ are the same as for C.

What makes it peculiar is the way the formats are specified - they are, needless to say, a bit cryptic...

Also, just a reminder - you may have to deal with byte ordering. This depends on how portable you have to make the code. Proper ordering guarantees the same data from sender and receiver, but isn't absolutely needed if both systems are ALWAYS the same type of system. One of the more interesting problems that can arise from this used to be communicating floating point numbers ... different machines would use different formats, so it was necessary to convert to something that both would know. Now that IEEE floating point is common, it usually just devolves into making sure the byte ordering is correct.

j-ray 08-14-2013 03:49 PM

What is a WIN32 structure? I've never heard of that yet. Wasn't WIN32 in some way related to MS?

But I guess it's a C-like struct used like documented:


package Myobj;
use Class::Struct;
# declare struct with four types of elements:
struct( s => '$', a => '@', h => '%', c => 'My_Other_Class' );

$obj = new Myobj; # constructor

# scalar type accessor:
$element_value = $obj->s; # element value
$obj->s('new value'); # assign to element


Anyway I don't know whether it will work in your program...

Good luck!

jpollard 08-14-2013 04:23 PM

According to its documentation, it was specifically to interface with libraries. I saw it with a windows 32 reference.

What I don't know is if that involved some differences - remember, MS doesn't exactly follow standards, so structure padding (usually at the end of structures, usually at byte/int/long boundaries) doesn't necessarily apply the same way as they would when used for a network communication message. It would be a good idea to ensure the "unused bits" were zero. Usually messages (unlike data structures) always terminate on a byte boundary... structures tend to have alignment bytes (one or more) added to bring it to a system level alignment (usually even number of bytes, but sometimes padded to an 8 byte boundary instead).

Using a C structure directly in a message sometimes works, but the sizeof operator can give the wrong size of a message. Whenever I was directed to send messages I had to encode the structure (with appropriate lengths for the structure, and every datum included) with byte length, data type, and the data itself. All with defined byte ordering for encoding and decoding.

It helps protect against security errors too (sending too much data - the recipient knows how much SHOULD be there, and can ensure availability, or that it is invalid, sending too few, invalid data types...). And when paranoid, include a checksum as well...

All parts of designing a protocol.

jpollard 08-14-2013 05:29 PM

A little follow on:
consider the following bit of code (a program that prints sizes and offsets):
Code:

#include <stdio.h>

struct demo {
    unsigned char  st_byte;
    unsigned short st_short;
    unsigned long  st_long;
};

#define offset(type,field) ((unsigned long) &(((type *) 0)->field))

struct demo data;

void main(void)
{
    fprintf(stdout,"size=%d\n",sizeof(data));

    fprintf(stdout," st_byte offset:  %lu  size=%d\n",offset(struct demo,st_byte), sizeof(data.st_byte));
    fprintf(stdout," st_short offset: %lu  size=%d\n",offset(struct demo,st_short),sizeof(data.st_short));
    fprintf(stdout," st_long offset:  %lu  size=%d\n",offset(struct demo,st_long), sizeof(data.st_long));
}

How many bytes? 7? or 10.. or is it 12, or is it 16 (answers below, this is not a test...:)

In a communication message, there are 11 data bytes: an unsigned character (one byte), a short integer (two bytes), and an unsigned long (8 bytes). In a sizeof operation on my system it is 16.

So the results:
Code:

size=16
 st_byte offset:  0  size=1
 st_short offset: 2  size=2
 st_long offset:  8  size=8

These offsets are to the beginning of the data - so the st_byte is the first byte in the structure.
Note the st_short offset - it is 2, not 1. So the storage allocated for the st_byte value is actually two bytes - of which only the first one is used.
Now the st_long offset - 8. not 3, or 4... so the structure storage for the first two data items (st_short and and st_byte) has to be 8 bytes... And its size is 8 bytes.

Since the total size of the structure is 16 bytes (from the sizeof).
EXPECT DIFFERENCES if you are on a 32 bit system (I'm using a 64 bit system). After all, a unsigned long on 32 bits is 4 bytes (well, last time used one, a very long time ago).

Without these pads included, you will not be able to call a C function and pass such a structure...

But if you send them over a network (as is in a message) you could also end up with something bad.

IF both systems are 64 bit, and the same byte ordering... it SHOULD work... but isn't guaranteed (data alignment remember - this structure is based on a 64 bit system with an 8 byte alignment). A simple "string of bytes" will not necessarily have that same alignment (the string is already part of another structure, I think perl uses a 32 bit int for length, followed by an array of bytes, so just passing it as is would not necessarily be on an 8 byte boundary - though I could be wrong on this, it might have the array aligned for this very reason).

Hence the STRONG recommendation to pack/unpack the data as needed...on both ends. Not how the C or C++ compiler puts it together.

chrism01 08-14-2013 07:37 PM

I agree that pack/unpack is probably the way: http://perldoc.perl.org/perlpacktut.html
2. do consider using network byte ordering
3. try posting this over at perlmonks.org, its where the Perl gurus hang out.
They'll likely want to see your c++ code as well.

Do post the soln, once you get it.


All times are GMT -5. The time now is 11:53 PM.