LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Accessing Enum properties without using VI Server Reference

Say I have a local Enum control. I can create a VI Server Reference and link it to the Enum. Using that Enum refnum I can access the properties of the Enum (e.g. Value, Strings[], and so on) using a property node.

 

My question is, is there any way to achieve the same thing as using VI Server Reference + Link in a way that takes the local Enum control as an input.

 

Assuming that the Enum is some sort of class in the background. I would have thought there would be some kind of "Get Enum Properties" VI. If I write a class and create Read/Write VIs for Data Member Access for a class with "Make Available Through Property Nodes" checked, I get a bog standard Read accessor that takes the class itself as input to read each property. Is this a deliberate design choice by LabVIEW and, if so, what is the thinking behind it?

 

By the way, the above method with VI Server Reference is fine for my needs, it's just something I'm curious about since forcing us to create a new local variable (the Enum refnum) which is separated visually from the control would seem to go against the dataflow idea for (at least in a visual sense). 

0 Kudos
Message 1 of 4
(634 Views)

@DavidCanning wrote:

 

By the way, the above method with VI Server Reference is fine for my needs, it's just something I'm curious about since forcing us to create a new local variable (the Enum refnum) which is separated visually from the control would seem to go against the dataflow idea for (at least in a visual sense). 


Most control properties (except the Value property) are NOT related to the value of the control and as such have no real data flow dependency in any way.

 

That said you can access the current enum value identifier by using a Format into String and the %s format specifier.

 

In vi.lib/utility/Data Type/Get Numeric Information.vi you have a function that can return the enum labels of a particular enum data type.

 

While the VI Server Reference has the performance issue of having to go through the UI thread to access the control properties, the above mentioned function has the performance issue of converting the enum into a variant and then parsing its type definition data for the relevant information. Both are not ideal but the only possibility to create a list of enum labels on the diagram.

 

Well there is a third, by typecasting a 0 integer with same size to the enum, decrement it by 1 and connect it to a for loop count terminal and inside the loop convert the iteration value to the correct integer size that corresponds with the enum, typecast this to the enum and use above mentioned Format into String to retrieve the enum label for that value.

Rolf Kalbermatter
My Blog
Message 2 of 4
(607 Views)

Rolf covered most of what I would have mentioned but I do have a couple things left to bring up.

 

If you're on a newer LabVIEW version (2020+)  there's an included VIM called "Enum to array of enums.vim", which converts (quickly) an enum into an array with one value of the enum per array element, in order.  If you combine that with the "Format into string" trick in a FOR loop, you can get a list of all string options quickly as well, and linked to your wire.  This is basically what he mentions at the very end with the FOR loop, but pre-made.

 

If you're on LabVIEW 2017SP1 to 2019, you can get the VIM here:

https://forums.ni.com/t5/Community-Documents/Natt-Sequence/ta-p/3970582

(Even if you don't need it for an earlier version, you also might be interested in the contents of the post just for educational purposes).

 

The other thing is that I would point out that even if not linked by dataflow, any "create reference" you do that you drop down should both have the same name as your enum control with the label showing by default, which is a pretty good pointer towards the original enum control, and if you do need to you can right-click it and use the "Find" menu to easily warp to either the control or the terminal, or even just double-click the reference and get sent directly to the control.  I've always considered those to be pretty strong linkages, even if they lack a visual wire connection.

 

Message 3 of 4
(571 Views)

@DavidCanning wrote:

Say I have a local Enum control. I can create a VI Server Reference and link it to the Enum. Using that Enum refnum I can access the properties of the Enum (e.g. Value, Strings[], and so on) using a property node.

 

My question is, is there any way to achieve the same thing as using VI Server Reference + Link in a way that takes the local Enum control as an input.

 

Assuming that the Enum is some sort of class in the background.


 

It is. That's why you can access its properties once you get a reference to the control. You can even get a feel for it's inheritance hierarchy by right clicking on a refnum control and digging through the "Select VI Server class" menu.

 

It is not, however, a by-value LVOOP class (.lvclass). VI Server classes and LVOOP classes are two rather different things. Properties and methods on VI Server classes are accessed by reference, and you need to obtain that reference before use.

 

The enum wire, on the other hand, is value based. It does not carry type information, only the value. This is similar to how some other languages work as well. For example, in C# an enum is a value type:

 

MyEnum value;
var names1 = value.GetNames(); // Doesn't work.
var names2 = Enum.GetNames(typeof(MyEnum)); // Does.

 

"names1" doesn't work. The "value" variable only stores an integer value. You cannot read type information, such as the names of all the enum members, from it because it does not contain that data. Trying to perform GetNames() on the variable itself is sort of like trying to pass an enum wire to a Property Node.

 

"names2" does work. You need to create a reference to the MyEnum type itself, which can then be passed to a static method that uses reflection to obtain the member names from the Type data. This is sort of like the convert to variant then read type definition data method Rolf mentioned, and like that method does have some performance impact. (VI Server is, I suppose, also kind of similar with the twist that you need to use a control reference so you're forced into the UI thread.)

 

Wires in LabVIEW are always value based, even when the value they are carrying is a refnum.

 


@DavidCanning wrote:

If I write a class and create Read/Write VIs for Data Member Access for a class with "Make Available Through Property Nodes" checked, I get a bog standard Read accessor that takes the class itself as input to read each property. Is this a deliberate design choice by LabVIEW and, if so, what is the thinking behind it?


The "bog standard" accessor VI still exists, however if you check that box you will find that you can also wire the class to a property node and it will have those accessors available.

 

Sometimes setting a property can have some side-effect or require some data validation or such. Still having the accessor VI is necessary to maintain the ability to implement functionality beyond simply reading/writing the object's private data. They are what the property node will use when accessing those properties. Using a property node vs. chaining a bunch of accessor VIs is (mostly) a style choice.

 

There are some that dislike this feature because it does work differently from how Property Nodes are normally used with refnums. I don't really mind it, but you could see it as mixing reference vs. value semantics.

Message 4 of 4
(557 Views)