LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Getting the Sizeof Clusters in LabVIEW

I need to fill a series of different clusters with data from a byte array.   Ideally, I would like one function that would work for different cluster typedefs.   To do that, I created a VI that takes in a general cluster reference and loops thru the cluster elements, getting the size of each element and reading that number of bytes from the byte array, then using those bytes to set the cluster element's value.  To make this work, I need to know the sizeof each cluster element.

 

Other discussion forum threads on sizeof said to flatten the control's value (which is a variant) to a string, then get the flattened string's length to get the sizeof the control. The problem is that the string created by flattening a variant contains a bunch of header info whose length and complexity depends on the data type of the control.  I have figured out how long the flattened string header info is for numeric types and array types, but not for other data types.

 

I have data types such as strings, arrays, clusters, and arrays of clusters within the cluster I am trying to fill from the byte array.  These data types make the flattened string so complex that I cannot decipher the sizeof the control from the length of the flattened string.  Clearly LabVIEW knows the length of any data type.  I really like LabVIEW, much more than any text based language, but this problem is frustrating because getting the size of any data structure in C is as simple as calling the sizeof function.  How can I get LabVIEW to tell me the length of any data type?

 

Thanks,
Hans 

0 Kudos
Message 1 of 21
(10,829 Views)

Hi Hans,

please see the OpenG library. There is a vi which shows you the type of each element if you connect the value as variant. This should help you.

 

Mike

0 Kudos
Message 2 of 21
(10,824 Views)

hans17 wrote:
I have data types such as strings, arrays, clusters, and arrays of clusters within the cluster I am trying to fill from the byte array.  These data types make the flattened string so complex that I cannot decipher the sizeof the control from the length of the flattened string.  Clearly LabVIEW knows the length of any data type.  I really like LabVIEW, much more than any text based language, but this problem is frustrating because getting the size of any data structure in C is as simple as calling the sizeof function.  How can I get LabVIEW to tell me the length of any data type?

LabVIEW does not, in fact, know the "length of any data type" for data types that can vary in size, namely strings and arrays.  C has the same problem - if you call sizeof() on a string, you'll get the size of a pointer to a string, not the string length.  When you flatten data to a string in LabVIEW, the flattened string contains information on the size of any variable-length data.  If you want to fill in variable-length information from a byte array you'll have to do a fair amount of work to determine where a string or an array should end.  Alternatively if you can live with fixed-size data you can convert your arrays to clusters (and your strings to clusters of U8s, which can later be converted to an array of bytes and from there to a string).

0 Kudos
Message 3 of 21
(10,817 Views)

Hi Nathand and Mike,

 

Thanks for your quick replies.  I do realize that the size of an array or a string is variable.  I hadn't thought thru that C's sizeof function may not be able to determine the string size.  C or LabVIEW ought to be able to return the size of a declared length character array or any other array with a declared length though.

 

For my LabVIEW sizeof VI, my plan is to fill any cluster array or string elements with data of the desired length prior to passing a reference to the control to the sizeof VI.

 

A little background on my project:  I am reading a data byte array that is coming from an embedded C programmed device.  The C program has a header file which defines the various data structures that are contained in the byte array.  All array lengths and string sizes are defined in these C data structures.  I would like to create LabVIEW cluster typedefs that exactly match the fields of the C data structure typedefs - so I really don't want to use fixed size data.   If I can get the sizeof each LabVIEW cluster element, including initialized arrays and strings, I can create a generic cluster filling VI which can read a byte array into any cluster whose structure exactly matches the C data structure that the byte array was created from.  That way, once a matching cluster typedef is created and its strings and arrays are initialized to the correct lengths, byte arrays created from any present or future C data structure could be read by the generic cluster filling VI.

 

Thanks again,

Hans 

0 Kudos
Message 4 of 21
(10,810 Views)

I think you are making this more complicated than necessary.  If you are willing to accept fixed-size data in your LabVIEW data types (as you are in your C program by declaring the size in the header file), you don't need any cluster-filling VI at all - you can use LabVIEW's typecast to directly convert your byte array into LabVIEW data.  You can build up your initial fixed-sized cluster using "array to cluster" so that if your C header changes you can just right-click once and update the cluster size.  If you have not already done so, take a look in the LabVIEW help for "How LabVIEW stores data in memory."

 

As far as I know, unlike LabVIEW, C provides no way to determine the length of an array even when the length is specifically declared.  The only way to get a string length in C is to iterate through each character until a null is found, regardless of the length that may have been declared for the string.  LabVIEW is able to provide string lengths and array dimensions because it stores that information as part of the data type; C treats an array as a pointer plus an offset without setting any limit on that offset.

0 Kudos
Message 5 of 21
(10,800 Views)

Hi NathanD,

 

Thanks for the reply and for your patience.  I looked at how LabVIEW stores data,  it was informative but didn't indicate to me how to programmatically determine the sizeof cluster elements.

 

I'm not seeing how array to cluster will work for my situation because while I do have control of the cluster definitions, I do not have control of the C data structures that are used to create the byte array which I need to decode into the clusters.  The C data structures are of mixed types - 8 bit uints, 16 bit uints, 32 bit uints,  arrays of 8 bit uints, etc. and I can't change them.  If the first element of the C data structure is a 16 bit uint, its value will be in the first two bytes of the byte array.  If the next element is a 32 bit uint, its value will be stored in the next 4 bytes.  If the next element is a string defined as a 12 byte array, its value will be stored in the next 12 bytes of the byte array...  

 

I am trying to download some applicable VIs from OpenG per Mike's suggestion, but it is a bit of a process since I am a OpenG newbie and needed to register, download and install VI Package Manager, and then try to guess which package might have a VI that might return the size of a cluster.  There's probably an easy way to search, but I haven't found it yet.  Also, when I try to install selected packages using VIPM, it acts like it is installing them, but then no packages show up in VIPM as installed and no new VIs show up on my functions palette.  Not sure what is up with that.  I'm approaching six degrees of separation from what I want to accomplish;)

 

I tried to attach an example VI and a couple cluster typedefs, but the NI web site said "An unexplained error has occurred".  Now I am six degrees separated!  Will try to attach in subsequent posts.

 

Hans 

0 Kudos
Message 6 of 21
(10,760 Views)
Sorry, the NI web site error message was actually "An unexpected error occurred".   Have not been able to attach the files, even one at a time.  Will try again in subsequent post.
 
Hans
0 Kudos
Message 7 of 21
(10,756 Views)

Here's an image of what I was trying to suggest.  Let me know if it needs further explanation.

Typecast from Byte Array to Cluster

Message Edited by nathand on 10-15-2008 04:40 PM
0 Kudos
Message 8 of 21
(10,752 Views)

Thanks once more NathanD.  I recreated your VI and played with it.  It does work, but it does not accomplish my goals.

 

1) I need a typedef-ed cluster because the cluster will be used in multiple VIs and I don't want them all to break when an element is added, deleted, or modified.

2) If I try to use a typedef-ed cluster as the type input to the Type Cast VI, an error is generated stating "This wire connects to a poylmorphic terminal that cannot accept this datatype."

3) I also want the typedef-ed cluster to be the sole item that needs to be defined or changed when new C structures are defined or existing C structures are modified.  I don't want to have to change the typedef and one or more VIs for C structure mods, and I don't want to create a new VI or modify an existing one to decode every new C structure I encounter.

 

I am open to other solutions, but if I can get LabVIEW to tell me the size in bytes of all the data types in a cluster reference, I can accomplish all my goals.  Is there a way?

 

Hans 

 

 

0 Kudos
Message 9 of 21
(10,745 Views)

The problem is not that you're using a typedef'd input to the Typecast, but that you have a variable-size element in your cluster and LabVIEW doesn't know how to typecast that because it doesn't know where the end should be.  You can create a typedef by creating a constant from the cluster in the code in my screenshot and use that; it will look slightly messy because the "string" sub-cluster will be large, but it will work.  If your string length were to change in the future you'd just need to replace that sub-cluster with one that contains the correct number of elements (slightly more work than clicking on "Set Cluster Size..." but not by much, and I assume you won't have to change it often).  I'd suggest this approach.  You'll be creating a type definition that matches your C data structure including the way it is laid out in memory.

 

There is no way to do what you're asking if you're going to use variable-size data types.  Somewhere along the way you're going to have to tell LabVIEW how long your fixed-size C strings are, and the cluster definition is the easiest place to do that.  You could probably come up with some more complicated solution in which you set the default value of your string to a string containing the right number of characters.  Neither LabVIEW nor C nor any other language will ever be able to tell you the length of an unknown string or the size of an unknown array, which is what I understand you to be asking.  How could LabVIEW tell you the size in bytes of an undefined string?

0 Kudos
Message 10 of 21
(10,739 Views)