LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

VI Refererence behaviour

Hi,

when I open a reference to a VI and then call This VI in the opened VI, why aren't they the same? I already have a workaround for my project but I wonder what causes this behaviour.

 

Minimal example where I had expected, that the IDs would be identical:

 

Main VIMain VISub VISub VI

 

 

 

 

 

 

 

 

 

0 Kudos
Message 1 of 23
(2,256 Views)

Hi Madir,

 

why do you want those references to be the same?

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 2 of 23
(2,250 Views)

Hi GerdW,

 

I work on an application where I have multiple datasets/records to edit. Everytime a user opens a dataset a panel is created using "Open VI Reference" and displayed in a SubPanel. All references together with the displayed names are stored in an array and the names are shown in a listbox. Clicking on the listbox allows changing between the datasets by choosing the entry from the array and putting the VI with the reference on the SubPanel. It works perfect so far.

 

Now I want the list entry to change its name, when a dataset is renamed. And so I thought I could simply use the reference delivered by "This VI" to search for the correct entry. But this doesn't work, because they are not identical. So an additional identifier transferred to the Sub VI and stored in the array will do the job but I still wonder why they are not the same, because they should refer to the same object.

 

Best

Madir

0 Kudos
Message 3 of 23
(2,241 Views)

LabVIEW refnums are a reference to an object. You can have multiple references to the same object but the normal comparison operator only operate on the reference, not on the data object that the reference refers to. This is a common difficulty about reference based systems, should comparisons be based on the reference or on the data object they point to?

After all the reference is the only thing that is known to be a certain amount of data, the numeric that represents the pointer or identifier. If you want to compare object data it gets a lot more complicated. How much of the data should be compared? The entire umptien MB the object may contain, bit for bit accurate? Aside that this is a performance nightmare, it may never compare equal as the object may contain temporary data that may change anytime at runtime. So someone has to specify at development time what specific elements of the object data determine if the object is equal. LabVIEW can't decide that generally for you, even for its own refnum based objects.

 

All reference based systems I know of by default compare the reference only. For object oriented programming there is usually a standard method to do comparison and a class will have to overwrite that method to implement a different comparison. LabVIEW does not have any documented way to overwrite its operators so you need to create your own methods and call them explicitly if you want to do such customized comparisons.

 

Basically each function that Opens or Creates a refnum in LabVIEW will return a unique refnum to the object even if that object already exists in memory. The Open VI Reference explicitly calls the word Open in its name and hence follows that rule.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 4 of 23
(2,217 Views)

Hi Rolf,

 

I'm not talking about the comparison of the data, I know that this is a different topic. Because then you can have two different objects of the same kind with the same data. It's clear that this comparision is more difficult, I know it from overloading the .equals() in JAVA many times.

 

But in my case (and in the minimal example above) there is only instance of the VI and both references mean the same. There is no second instance which would require a comparision of data. I was thinking, that the reference is working like a pointer to the VI in memory and then it should be the same no matter where I get the reference from. But it's working in a different way and I don't know how to find out if the current VI is identical (not only the data) to the one I opened and stored in the array. 

 

Best

Madir

0 Kudos
Message 5 of 23
(2,206 Views)

You don't need the numeric values to be the same.  Starting around LV 2008, NI made the comparisons smarter: When you wire two references to the "Equal?" or "Not Equal?" functions, it doesn't check whether the numeric values match, it checks whether the references refer to the same object.  Also, the "Search 1D Array" is smart: If it's an array of references, it searches for a reference to the matching object, regardless of the numeric value of references.

"If you weren't supposed to push it, it wouldn't be a button."
0 Kudos
Message 6 of 23
(2,203 Views)

@mp_db_21 wrote:

 

But in my case (and in the minimal example above) there is only instance of the VI and both references mean the same. There is no second instance which would require a comparision of data. I was thinking, that the reference is working like a pointer to the VI in memory and then it should be the same no matter where I get the reference from. But it's working in a different way and I don't know how to find out if the current VI is identical (not only the data) to the one I opened and stored in the array. 


Well a reference is a pointer of some sorts and you can have two pointers referencing the same object of course. 

 

But as Paul Cardinal points out, if your VI is not configured to be reentrant (shared or preallocated clone) the equal operator should work if you use it for the refnums instead of the typecasted integer values. Once it is configured as reentrant things get more difficult as you will end up with individual objects for Open VI Reference calls if you use any of the option flags (0x08, 0x80 or 0x100) to open a reentrant clone.

 

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 7 of 23
(2,193 Views)

@mp_db_21 wrote:

Hi,

when I open a reference to a VI and then call This VI in the opened VI, why aren't they the same? I already have a workaround for my project but I wonder what causes this behaviour.

 

Minimal example where I had expected, that the IDs would be identical:

 

Main VIMain VISub VISub VI

 

 

 

 

 

 

 

 

 


Your example is flawed.  As others have mentioned the Ref ID Cast to I32 should not be the same as you open 2 references to the same object (.../SubVI.vi).

 

Additionally,  you are using the Run VI method where you should be using the Asynchronous Call By Reference node.  If you edit your SubVI.vi to accept a vi reference input from the caller you can compare that ref with a ref to This VI.

 

Now for the pesky details you forgot. 

  • Is SubVI.vi re-entrant?  Then you might want to assure the ref is of the same Clone
  • Is SubVI.vi inlined? (Actually that would break SubVI.vi) This VI would have to be That VI , the caller it is inline with.
  • If the refnums as I32 values were identical, what happens to instance A when you close instance B?  ~~~~ohhhh, that sounds spooky ~~~~

Trust us, you want exactly the implementation you just observed!


"Should be" isn't "Is" -Jay
Message 8 of 23
(2,187 Views)

Thanks again!

 

The direct comparison of references was my first test and it worked until I found out that it renames all my open datasets because the VI is preallocated reentrant. So I can simply have multiple panels each with it's on data in the input fields and no need for manual handling when switching between the panels.

 

So I guess creating an additional identifier for each panel, storing it in my array and handing it over to the panel on opening is the easiest way to solve it.  

0 Kudos
Message 9 of 23
(2,181 Views)

@mp_db_21 wrote:

Thanks again!

 

The direct comparison of references was my first test and it worked until I found out that it renames all my open datasets because the VI is preallocated reentrant. So I can simply have multiple panels each with it's on data in the input fields and no need for manual handling when switching between the panels.

 

So I guess creating an additional identifier for each panel, storing it in my array and handing it over to the panel on opening is the easiest way to solve it.  


No, you want to be using the Asynchronous Call By Reference and each reference out of the ACBR will be a ref to that Clone instance.  In othe words, let LabVIEW do all that for you you don't need to reinvent the wheel.


"Should be" isn't "Is" -Jay
Message 10 of 23
(2,176 Views)