LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Limitations of embedded GOOP

I heard they put tools into LV v8.2 to support object oriented programming. I have been using a pseudo-OO apporach in LV for years, so I thought I would finally take the opportunity to investigate what they have. I reviewed the online info, watched the relevant presentations from NI Week, and worked with the LV Help as I attempted to used the new tools to solve 2 tasks; one simple and one complex. In the end, I failed to see how it would be useful for EITHER task!!

 

I hope that I have reached this conclusion in ignorance, and that someone can point me in the right direction.

 

Task 1

The first task was to replace the method that I currently use to store program variables to disk when an app shuts down, and read them again on startup next time so the app appears to "pick up where it left off." Currently I have one large cluster with ~12 separate controls (some of them type-def'd) that I write/read as a datalog file (basically as a native cluster). From time to time I am forced to change or add to this cluster, changing the data type. But, I must continue to support files that were created in all previous versions. I thought this would be a good task to try out in GOOP, and I had heard from somebody else that went to NI Week this year that it was very easy to do in GOOP.

 

In the end, I did not see a reasonable way to do this with GOOP. I thought perhaps I could start with the parent class as version 1. My first modification (to my cluster; maybe adding a new control) would be version 2, which would be a child of the parent. The subsequent change would be version 3, which would be the grandchild, and so on. With this approach, I found I was able to write parent/child/grandchild with a parent subVI (class was coerced to parent before writing). If I knew how to interpret the data that I read back from disk, I was able to read it as a parent, and type cast it to a more specific class to generate a child (I only tried this for child, not grandchild). But what happens when I don't know what version it was on disk? How can I find out? Do I have to explicitly put a version tag/number as a data member of the parent and keep that updated before writing to disk? If so, how do I get that data out (after reading from disk) to determine how many times to cast to more specific child? For this application, each parent class would have exactly 1 child class, and the last version (class) would have no children. The goal is to have the output of this operation be an instance of the latest version (class).

 

Task 2

The more complicated task was a typical programming issue that required private data and methods to do things with that data. However, this capability is required at a variety of places in my software. For instance, I can cause updates to portions of the private data based on user input. My user input comes from a state machine with event structure. Other data are updated, and sometimes outputted from the object in a loop that is conducting TCP communication with other computers. This loop is completely separate from the event loop. There are other, asynchronous loops that also need access to the data. 

 

 When I split the wire (chain, actually) in LV to send (what I thought was) a single instance to multiple, simultaneous loops, I got a big surprise!! LabVIEW duplicates the data!! I thought it would operate like pointer/references, just like the IMAQ images. Not so!! The only way I could figure out to use the GOOP tools for this task was to wire the instance of the class I wanted to a global variable. But, in doing that, I would also have to implement a semaphore for it to prevent race conditions. This does not seem at all feasible, especially when compared to the simplicity of my current technique using a LV2-style global (while loop with uninitialized shift registers) inside a non-reentrant subVI (to act as blocking node, natural semaphore) with an enumerated list of "methods."

 

Can anyone provide suggestions for a better way to use the GOOP tools?

 

Many thanks,
Derek

0 Kudos
Message 1 of 3
(2,297 Views)

I don't have a soln for your issue but a few comments. By what you mean by "embedded GOOP", I assume your referring to NI implementation of Object Oriented Programming. NI has dubbed this OOP. As you found out NI OOP is based on dataflow still and not references to the data.

 

There is also an addon Tool dubbed "GOOP" thats been around since the 90's, made by Endevo and maybe other flavors out there besides Endevo. This brand of Object Oriented Programming uses references to create and kill quote-unquote "Objects".  They dynamically call child classes using "Dynmaic call VI" on the block diagram (unlike NI's OOP which is strictly dataflow)!

 

So you have two competely different avenues of accomplishing OO programming. They can even be used together in your code... Endevo has a "Wizard" for created classes and it provides the OO functionality like a black box I/O. I think your referring to NI implementation of OO and I've only done the examples myself... As you think about your application you'll find there is more code to write upfront but easier to maintain if its very large...

0 Kudos
Message 2 of 3
(2,286 Views)

I haven't tried it, but the class version is saved when you flatten a class to save it to disk and loading an older version of the class should translate the data correctly to the new version. I don't know of any official documentation explaining when this will or won't work. Also, there are some freeware tools (from OpenG and MGI) which allow saving and loading arbitrary clusters which maintain the data even if the cluster is changed.

 

As for the LVOOP details, here and here are a couple of links you can start with. Be sure to read the second link, because LVOOP is different from C++ OO and it explains the by-ref vs. by-val issue.

Also, you can find LVOOP examples in the example finder (Help>>Find Examples). Also, the LAVA forums have a pretty detailed forum for LVOOP which you can read.

 

Lastly, as mentioned, there are alternatives for doing by-ref, including some free ones. These include OpenGOOP, dqGOOP, Sciware GOOP, Endevo GOOP and probably some others.


LabVU_Dog wrote:

The only way I could figure out to use the GOOP tools for this task was to wire the instance of the class I wanted to a global variable.


That should not work. When using a global, the instance should be duplicated. As mentioned, there are shipping example showing how to do by-ref.


___________________
Try to take over the world!
0 Kudos
Message 3 of 3
(2,255 Views)