LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LabView OOP - nest independent running VI in Object - bind vi execution to object

I have a problem, which I dont find any way to get rid off.

 

I have a LVobject. Inside I have the

- private Data 

- a VI called startupMain.vi

- a VI called main.vi

(- a global variable)

 

I want to start up the main.vi via asynchronous call from startupMain.vi which works so far. For each startup I get a own instance of main.vi running.

Now I want to access from main.vi the private object data, in a similar way I use global variables. I haven't found any way to perform this. If I use a global variable (and put data there instead of privateData.ctl) with access restriction (protected), it is still shared with all other instances of main.vi.

 

Another approach was to put a list of all object instances into a list inside the global variable and the list index inside private data. Then this index is passed to main.vi and kept alive there. But this doesnt work, because LVobjects are passed by call by value instead of call by reference. So a copy of the object would be stored in the global variable and never changes again (and could cause an error because of recursion). If I could reference the LVobject by a reference, this approach would work.

 

Since the LV-Objects behave like cluster with read/write restriction, I guess a feature like execution memory bound to a LVobject is not available. Only data memory.

 

I hope you get what I mean.

0 Kudos
Message 1 of 19
(3,418 Views)

What is wrong with using a bundle/unbundle on the Object wire in your main.vi method? 

As the main.vi is part of the class and you have the Object of the class as input, this is the normal way. 

 

Or do you need to acces common data across the different objects of the same class that you are running? 

0 Kudos
Message 2 of 19
(3,397 Views)

@dkfire wrote:

What is wrong with using a bundle/unbundle on the Object wire in your main.vi method?


They mean a “Main.vi” that is running asynchronously, in parallel to the code that has the object.

 

I recommend the OP look into the “Actor Model”, where the “private data” is private to the “Main.vi”/actor equivalent, rather than being by-ref accessible everywhere, and information is accessed by exchanging messages (my implementation is part of Messenger Library).  However, to do exactly what they’re asking I suggest using a DVR as a by-ref data store.  One DVR per “Main.vi”.  One can do either a DVR of the object, or an object that holds a DVR of the private data.

Message 3 of 19
(3,389 Views)

I need a asynchronous call, because I cant wait for end of execution. But I need a possibility to pass still data to main.vi afterwards. It would be nice to have something like the DLL_Main in a dll. If I pass the object to main.vi, it misses updates of the object variables, because it got a copy of the data. 

 

I pass the object to main.vi -> I change the object data later outside main.vi -> no change in main.vi.

 

Of course there are possibilities, but they would make the OOP approach obsolete.

0 Kudos
Message 4 of 19
(3,384 Views)

That was also what I was think about. But it was not clear if the OP needs to read the object data outside of the main.vi. 

 

I would also go with some kind of communication model like in a Actor model. 

 

Using the DVR model, you need at way, like a object constructor, to generate the DVR for each object before launching main.vi and splitting the object wire.  

0 Kudos
Message 5 of 19
(3,382 Views)

Asynchronous code can communicate though 1 element queues or DVR's (basically data by reference, not by wire).

 

I do this sometimes (when it cannot be avoided) for small utilities. For instance, .net callbacks are also async VI's, and sometimes you need to communicate data back and forth. As an architecture feature it seems you're adding a lot of complexity just to get things started. 

 

 

It's hard to advice on better approaches, we don't know all the details. But starting normal dynamic VI's, and then communicating with them with user events seems less complicated. In the dynamic main VI's you can use all the OO you want.

0 Kudos
Message 6 of 19
(3,346 Views)

I tried to get a strict encapsulation. DVRs and producer-consumer structures are a solution for the problem, but it makes the OOP obsolete. For my question there is a simple answer: There is no solution. At least no handy one.

 

My optimum solution would have been an actor which can access the private data.

 

Thanks so far. I will put up a feature request.

0 Kudos
Message 7 of 19
(3,329 Views)

How do DVRs make OOP obsolete? In your abstraction, create wrapper methods that take in a reference to the class, then call the needed function inside the in place element structure. So in your 'By Reference Init' method, you take in the DVR reference and inside the IPE structure you call the Init method. You dont lose anything there.

 

Alternately, you could have a child class that stores a DVR of your parent class in its class data, and all it's overrides of dynamic dispatch methods just call the DD method inside the IPE. I have used both approaches for getting by reference behavior with classes. 

 

Data is still encapsulated and you can still use polymorphism/inheritance..

 

0 Kudos
Message 8 of 19
(3,325 Views)

DVR's work as good in classes as outside classes. Using a DVR in a class's private data does not expose anything, it's still perfectly good OO.

 

However, every time I thing a DVR is a good idea, I refactor them out eventually. They are a pain to debug, as you can't run subVI's once the main VI is stopped (the DVR is destroyed the moment the hierarchy it was started in is stopped).

 

Since LV is by wire, by reference is often just a bit off. I'd consider not using a by reference architecture. You can still synchronize data or distribute classes. But you'd do this through user events. This might seem like a hassle, but to me it is a lot clearer.

 

You are looking for a structure where you have the same object in several parallel loops. Another approach would be to have one loop that deals with the object, and let the other parallel loops communicate with. That would basically avoid the problem altogether.

 

But suit yourself...

0 Kudos
Message 9 of 19
(3,307 Views)

I had success with the main.vi having a dynamic class control, and checking to see if main.vi was running/idle to either pull/push control data from/to the object and VI.

 

See the attached minimal example project, the meat of it is in 'SubWindow[init or connect to inited VI].vi'

 

Class summary:

_SubWindow.lvclass A ancestor for multiple applications using Subpanel+subVIs for UI design

SBLSubWindow.lvclass A specific project implementation.

SBLSubWindow Viewer.lvclass A UI SubVI for deployment to a subpanel control.

SBLSubWindow History.lvclass A UI SubVI for deployment to a subpanel control.

 

Is this similar to what you are trying to do?

________/~~~~~~~~*********~~~~~~~~\________
Certified delinquent LabVIEW developer. Recertifying at next NI Days
0 Kudos
Message 10 of 19
(3,076 Views)