LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

pass cluster to sub vi

Solved!
Go to solution

Hi,

 

I want to pass a cluster which might change its content to a sub VI. The cluster does not change programmatically, but during programming, i.e. I might add or remove elements to/from the cluster. By using local variables or direct wiring I would have to change each sub VI that uses the modified cluster. I also tried typedefs but I encountered the exact same problem.

At the same time, the subVi should be able to update the cluster I passed.

 

In C++ I am using classes as struct (equivalent to LV cluster) and pass a pointer of a class object to a function. Within the function, I pick the class members I want to use inside that function. If I change the structure of the class, the functions I call are not affected (of couse only as long as I don't remove class member relevent for the called function).

 

Example (C++ snippet):

 

parameters *param;  // 'parameters' is a class that I use to bundle variables

 

doSomethingUseful(param);

 

/* the function doSomethingUseful takes the pointer to param and accesses the members by

param->variable1

param->variable2

...

 

By this I can change the values of all variables stored in the object param

*/

 

Best,

Max

 

 

 

 

0 Kudos
Message 1 of 12
(4,651 Views)

Why wouldn't you do it that same way in LabVIEW?  Create a class that contains all the members you need and then do exactly what you are doing in the C code.

Randall Pursley
0 Kudos
Message 2 of 12
(4,642 Views)

MaxGreisel wrote:

I want to pass a cluster which might change its content to a sub VI. The cluster does not change programmatically, but during programming, i.e. I might add or remove elements to/from the cluster. By using local variables or direct wiring I would have to change each sub VI that uses the modified cluster. I also tried typedefs but I encountered the exact same problem.


A type definition is the correct approach. Can you elaborate on "encountered the exact same problem"?

 

You need to replace every instance of the cluster with the type definition - this doesn't happen automatically. Once that's done, any change to the type definition will update every instance of that type definition. It might also help to attach a project, with subVIs and type definitions, showing where the problem occurs for you so we can check that you haven't missed something.

0 Kudos
Message 3 of 12
(4,628 Views)
Hi, thanks for the replies! @Randall: That's a very good question. The only reason is, that I am not familiar with LV OOP. But from what I understand is, that there are no pointers in LV. So how would I implement the C++ aproach to LV (passing a pointer to an object)? @nathand: Ok, after replacing every instance im my subVIs it worked (Changing something in the typedef changed the clusters in all subVIs). However, now I can only pass a local variable (or a wire) to the subVI. Consequently, if I change the cluster in a subVI it does not change the cluster in the calling VI, as I passed a copy of the cluster (not a reference). I guess I would have to pass a reference to the cluster, but how?
0 Kudos
Message 4 of 12
(4,579 Views)

To get a reference to you cluster you should look at Data Value References (DVRs). Create a DVR with yout type def:ed cluster as type and pass the DVR around instead of the cluster. The you access the data using the In Place Element structure. DVRs are found under Application Control -> Memory Control.

 

You could also create reference based objects but you'd need to understand LVOOP first. And then the most common implementation for this still relies on DVRs.



CLA
www.dvel.se
Message 5 of 12
(4,570 Views)

Hello Max,

 

I believe the LabVIEW concept you are looking for is Data Value References, there are more than a few tutorials on the subject, but here's one with some basic information on using DVRs with and without LVOOP that should get you started:

 

Tutorial: Reduce Memory with Data References

http://www.ni.com/white-paper/9386/en/

 

Rather than passing copies of the cluster around, you'll be passing a pointer to the data encapsulated by the class or data type you've defined. Note the green border added to the wire created by the New Data Value Reference function to signify that you're passing by reference rather than by value.

 

One thing to note is the structure used to access these references - the in-place element structure.  This can be found in the Structures palette.

 

Hope that helps!

Tom L.
Message 6 of 12
(4,569 Views)

Before you get into DVRs, see if a much simpler approach will work for you: create both a control and an indicator for the cluster, making the cluster both an input and an output of your subVI. If you structure your code properly, LabVIEW will operate on the cluster elements "in place" - it will reuse the same memory for the input and output, rather than making a copy of the entire cluster. Any changes you make to the cluster will, of course, be seen in the output cluster. This is the standard and recommended way of handling this situation (a subVI that needs to modify a structure) in LabVIEW.

Message 7 of 12
(4,549 Views)

nathand,

 

how do I make a control and an indicator for the cluster? By defining the cluster twice (once as a control, once as an indicator) and then define the same typedef for both? Then I would have two clusters with the same content on the front panel, which would be a bit odd.

 

 

0 Kudos
Message 8 of 12
(4,504 Views)

There is also a function called New Data Value Reference located in

 

Application Control>>Memory Control

 

That you can feed your class into to create a by reference wire that is essentially a pointer.  If you wanted you could use it for a cluster as well.

 

You could also replace the indicator with a local variable of the control so it would write to the same control it originally read from.

Randall Pursley
Message 9 of 12
(4,487 Views)

Hello Max,

 

It's not odd at all to have matching inputs and outputs on a subVI, if anything this is the most common configuration if you need to modify the data contained in your cluster or protect against race conditions in accessors. 

 

Note that wiring things into and out of a SubVI is a by-value approach that leverages dataflow, not by-reference like the DVRs also mentioned in this thread.

 

As for creating the control/indicator clusters, you should define (and save) your type definition, then drop an instance of that .ctl in your front panel (for controls and indicators) or block diagram (for a constant).  Right-click on a front panel object to change it from a control to an indicator.

 

The two clusters in question (control and indicator in your subVI) would only have identical data if they were not modified.  In this case, it can definitely still be advantageous to wire your cluster "through" the subVI as this semi-protects the data contained in the cluster against race conditions, allows in-place modification of the cluster, and also (potentially, with good practices) prevents additional copies of the data due to branching the cluster. This also helps debug down the road since the flow of the application should be easier to follow - the cluster goes from one function to the next rather than branching all over the place.

 

Best Regards,

 

Tom L.
Message 10 of 12
(4,461 Views)