LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

c structure

How does one convert a "c structure" that has been sent via a TCp/ip or UDP packet. Within a c program there is a structure that gets sent as a packet but on the LabView side it comes in as a binary string - There seems to be no way in Labview (at least the widgets given) that allow me to set up a labview structure so that I can point to the incoming data and pull out the data that is needed.  In C one can do this by pointing to the same structure (IE copy of the TCP/IP structure).
 
Thanks
 
GG
0 Kudos
Message 1 of 29
(4,628 Views)

The closest Labview equivalent to a C structure is the Labview cluster.  However, they are not exactly interchangeable.  There are limitations.  I have successfully passed LV clusters into a C structure once before but the data elements were simple numerics and a fixed length string.

If you would describe the structure, one of us may be able to help you.  If it is not practical to create a cluster which is equivalent to the structure, you will have write some wrapper code in C to transform the structure into individual elements and vice versa.

- tbob

Inventor of the WORM Global
0 Kudos
Message 2 of 29
(4,613 Views)
There may not be an EASY way - you have to consider:
  • Byte order. LabVIEW uses big-endian order - your packet might be in Intel order. That affects any number larger than one byte.
  • Strings - C strings are characters followed by \000, LabVIEW strings are a U32 followed by characters.
  • Padding issues. Everybody has their own alignment / padding strategies, that might be a consideration.
All of these are overcomable (is that a word), but not with a simple function.
Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 3 of 29
(4,599 Views)
Thanks for the reply the struct looks like this
480 bytes
{
DWORD Counter;    //4
unsigned char status //1
bool Mode                  //1
unsigned short Yr      //2
double timedevice     //8
unsigned char TimeSource //1
unsigned char NumStreams //1
unsigned char sStatus[STREAMS]  //8
double sTime[STREAMS]                //72
double sRate[STREAMS]                 //72
char Name[MAX]                               //256
DWORD OvflCount[STREAMS]      //32
unsigned char Spare1                      //1
unsigned char Spare2                      //1
DWORD dSpare                              //4
double spareD                                  //8
}         
 
Any ideas tbob - using a cluster seems to be the right direction but not sure how to transform it - not exactly interchangeable like you have said.
 
0 Kudos
Message 4 of 29
(4,585 Views)
Hi greif,

I assume you get a string of 480 chars or as a byte array (which you can get from the string as well).
The simple, but ineffective way of solving this would be to use array subset, (byte order correction using swap words/bytes), typecasting to needed type for each component of the struct!
Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 5 of 29
(4,570 Views)

Hi Grelf,

      Any chance of your posting the actual binary data?  I'm curious about how the array-data is packed.  It looks like there's an extra 8 bytes with both the sRate and sTime arrays.  If both those lengths are really 64 (no structural info) then with a little fudging you can probably cast the binary string straight into a structure - I mean cluster. Smiley Wink  I was thinking about reversing the byte-order of the binary-string to take care of endian-ness all at once, and creating 8-element clusters for each of the arrays.  There might be some byte-padding issues with the chars, maybe not, either way it seems promising. Smiley Happy

Cheers!

Message Edited by tbd on 08-24-2007 03:15 AM

"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
0 Kudos
Message 6 of 29
(4,563 Views)
I would write a CIN or DLL (in C) to accept a LabVIEW string (which you received via TCP), and spit out a cluster.

the C code would do all the byte-swapping, and construct a LabVIEW string from a C string.

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 7 of 29
(4,543 Views)

Tbd - point taken with the extra bytes - The data that comes from the TCP/Ip or UDP packet is nothing more then a string of bytes that fill the packet that is sent. It is up to the end use to decipher what those bytes really mean. Within a C structure this is a simple task since we point to a memory location that holds the sent packet. Based on the inputs that I have been receiving it seems that one can store the infor within an array (byte) then extract the bytes as needed ( byte swap etc) and then send to a cluster- sounds painful indeed or write a c program that translates a packet string of data into a cluster which is basically the same. It does sound like what would be nice is if the cluster could point to the memory location of where the data lies and extract according to what the elements are within the cluster. A cluster that can reference a memory location (just a thought that popped out) - thanks for the inputs, time to try a few of them and see what happens unless someone knows of a way to reference a memory location.

 

GG

0 Kudos
Message 8 of 29
(4,531 Views)
If you search NI's website, there is a document that lists C data types and the equivalent Labview data type.  Sorry I don't have the time to search for it myself.  But an example would be that a C unsigned char is a U8 in Labview.  A DWORD might be a U32 or I32.  So make your cluster in Labview with the equivalent data types in the C structure.
Before passing into a Call Library Node, you have to manipulate arrays and strings:
The string must be a fixed length or this won't work, and you would have to use a wrapper DLL.  If the string length is known, use the String to Byte Array function to turn the string into an array of U8.  Then use the Array to Cluster function to turn the byte array into a cluster.  Right click on the function and set the size of the cluster to the size of the original fixed length string.  Send this cluster into a Bundle Cluster function.
Any numerical array must be converted into a cluster also, just as the byte array described above.  Be sure to set the cluster size properly.
All of your cluster elements should be in the same order as the C structure.  After changing the strings and arrays to clusters, bundle all elements into one cluster.  Numericals can be sent straight into the bundle function.  Then use the Call Library Node and send the cluster into it as a parameter.  You must configure the Call Library parameter for Data Type = Adapt to Data, and there is another setting that defines the passing as Pointer to Data.
Here is a small snippit on how to pass a cluster of Numeric, String, Numeric Array.  Hope this helps.
 

Message Edited by tbob on 08-24-2007 09:50 AM

- tbob

Inventor of the WORM Global
0 Kudos
Message 9 of 29
(4,522 Views)

Hi Greif,

      Without some data to practice with, I'm not as confident that this will work, but if endian-ness is applicable uniformly (that is, all data-types are byte-swapped LSB to MSB) and if MAX is always 256, and if STREAMS is always 8, then the solution might be as simple as this:

The [nested] clusters (sRate/sTime and Name) can be cast-back to arrays or strings in LabVIEW. Smiley Happy

Cheers:

Message Edited by tbd on 08-24-2007 05:48 PM

"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
Download All
0 Kudos
Message 10 of 29
(4,498 Views)