LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 08-14-2013, 01:18 AM   #1
Shahid nx
Member
 
Registered: Jan 2012
Posts: 46

Rep: Reputation: Disabled
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..

Last edited by Shahid nx; 08-14-2013 at 01:21 AM.
 
Old 08-14-2013, 03:20 AM   #2
j-ray
Senior Member
 
Registered: Jan 2002
Location: germany
Distribution: ubuntu
Posts: 1,532

Rep: Reputation: 132Reputation: 132
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
 
Old 08-14-2013, 01:32 PM   #3
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,604

Rep: Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241
Quote:
Originally Posted by j-ray View Post
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.

Last edited by jpollard; 08-14-2013 at 01:37 PM.
 
Old 08-14-2013, 04:49 PM   #4
j-ray
Senior Member
 
Registered: Jan 2002
Location: germany
Distribution: ubuntu
Posts: 1,532

Rep: Reputation: 132Reputation: 132
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!
 
Old 08-14-2013, 05:23 PM   #5
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,604

Rep: Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241
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.

Last edited by jpollard; 08-14-2013 at 05:26 PM.
 
Old 08-14-2013, 06:29 PM   #6
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,604

Rep: Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241
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.

Last edited by jpollard; 08-14-2013 at 06:30 PM. Reason: bad arithmetic on my part.
 
Old 08-14-2013, 08:37 PM   #7
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.8, Centos 5.10
Posts: 17,240

Rep: Reputation: 2324Reputation: 2324Reputation: 2324Reputation: 2324Reputation: 2324Reputation: 2324Reputation: 2324Reputation: 2324Reputation: 2324Reputation: 2324Reputation: 2324
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.

Last edited by chrism01; 08-14-2013 at 08:38 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Extract the first numeric character from a string patmut Linux - General 2 07-04-2012 04:29 AM
POSIX Queues with message type facility of System V queues ehsan_haq98@yahoo.com Programming 2 12-27-2009 12:45 PM
Split string and numeric with perl kariagekun Programming 4 11-05-2009 08:31 PM
How to send and receive data from a single socket in perl?? murahman Programming 0 07-28-2008 04:29 AM
POSIX message queues(Solaris) to SYS V message queues(Linux) devershetty Programming 1 01-22-2007 11:15 AM


All times are GMT -5. The time now is 12:33 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration