03-31-2014 10:02 AM
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
Solved! Go to Solution.
03-31-2014 10:47 AM
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.
03-31-2014 12:15 PM
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.
04-01-2014 09:49 AM
04-01-2014 10:03 AM
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.
04-01-2014 10:04 AM
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!
04-01-2014 11:37 AM
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.
04-02-2014 04:52 AM
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.
04-02-2014 07:57 AM - edited 04-02-2014 07:58 AM
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.
04-02-2014 10:40 AM
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,