LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

equivalent of C++ static member variable in LVOOP

Good morning dear community,

 

I am looking for the best practice when it comes to the equivalent of C++ static member variable in LV Class Object. 

 

Let's assume I have Parent A with multiple child. And that all the childs share a common static member variable from the parent class. (Please it is irrelevant to ask why would you do that as I saw this question often in other posts).  

 

I have looked different topics and couldn't find a proper answer. So far, I have been using a Data Reference stored in a FGV - VI. But, I feel this is so much work and I can't believe there is something much simple similar to other programming languages. 

 

If you have a link reference or an example, I am thanking in advance for sharing it.

 

Kind regards,

0 Kudos
Message 1 of 10
(1,386 Views)

There isn't a great or simple solution here.  Since LabVIEW is by default a "by data" language and not "by reference", anything that is "by reference" is always going to feel less than optimal to use.

 

The best you can really do is try to make all of the "work" just happen once and then abstract it away whenever possible.  In this case, it probably means making a wrapper for your data reference to read the value, making it look like a simple read accessor, and then carefully making one or more write accessors depending on how you use your data (i.e. if it's a single scalar value just a single VI that looks like a write accessor should be fine, but if it's a complicated cluster you might need a write accessor for every member, or you might need to make some "modify" accessors that combine read-modify-write all in one VI).

 

As for the exact method, using a DVR is pretty standard but a FGV can occasionally run into problems later, notably if you try to use it in multiple packed libraries.  For that reason, using a single-element named queue (with a fixed name, unique enough not to ever accidentally collide) containing either your value or a DVR is probably the best, because of all of the various "global" implementations it's the only one that crosses the packed library "border".

Message 2 of 10
(1,365 Views)

The short version:  You are already using the best answer I can think of with a LabVIEW implementation.

 

The bottom line is that LabVIEW is a dataflow language, and there are some constructs in other OOP languages that didn't translate well to LabVIEW. Some of these decisions were made because it wasn't technically feasible and others were made because it didn't fit well within the dataflow paradigm of LabVIEW. You can read a writeup on some of these decisions here.

 

I know this is so frequently the answer on programming forums that it has become a meme... but in the end, if you are trying to force a design pattern from another language into the constraints of LabVIEW and it isn't working, you might want to redesign. There are always multiple ways to solve a problem, and I have never run into one that I couldn't resolve in a way that felt more "LabVIEW" than not, though sometimes it takes me a few failed (but still implemented 😣) attempts before I found a solution I liked.

Message 3 of 10
(1,351 Views)

@Kyle97330 wrote:

For that reason, using a single-element named queue (with a fixed name, unique enough not to ever accidentally collide) containing either your value or a DVR is probably the best, because of all of the various "global" implementations it's the only one that crosses the packed library "border".


I would be hesitant with this solution because I don't know of any way to keep a single-element named queue as entirely private data to a class. It would be a good way to pass your data around, but it would be public

0 Kudos
Message 4 of 10
(1,348 Views)

I


@BowenM wrote:

@Kyle97330 wrote:

For that reason, using a single-element named queue (with a fixed name, unique enough not to ever accidentally collide) containing either your value or a DVR is probably the best, because of all of the various "global" implementations it's the only one that crosses the packed library "border".


I would be hesitant with this solution because I don't know of any way to keep a single-element named queue as entirely private data to a class. It would be a good way to pass your data around, but it would be public


If any programmer is sufficiently determined, unless you password-protect every block diagram in your code or only distribute binaries then anything "private" is no more than just a strong suggestion.

 

Queue names can be made sufficiently long to prevent accidental "public" changes.

0 Kudos
Message 5 of 10
(1,342 Views)

Thanks for you answer guys, I see that this is a know problem and solved only by workaround as I do. 

 

@BowenM, you may have right and should learn more how to build complex architecture in LabVIEW style than simply using the same type of architecture of other languages. 

 

So my solution so far is to have an init function that create a reference to the shared data (can be a cluster) on the first call only and stores it in a shift register, then all other class will also call the init and simply read and stores the reference. Than I have Getter/Setter (Public/Private) to individual element of the cluster using that reference. 

- pro: easy to implement

- cons: cannot use bundle/unbundle on the class wire to access the data. (I don't think any solution can)

 

Cheers,

0 Kudos
Message 6 of 10
(1,286 Views)

@Redzouz1 wrote:

I am looking for the best practice when it comes to the equivalent of C++ static member variable in LV Class Object. 

 

Let's assume I have Parent A with multiple child. And that all the childs share a common static member variable from the parent class. (Please it is irrelevant to ask why would you do that as I saw this question often in other posts).  

 

I have looked different topics and couldn't find a proper answer. So far, I have been using a Data Reference stored in a FGV - VI. But, I feel this is so much work and I can't believe there is something much simple similar to other programming languages. 


Perhaps you should explain more exactly what your application is.  Looking up what a C++ Static Variable is, it could map partially onto a range of LabVIEW techniques, many of which are simpler than the techniques being described in this thread.

0 Kudos
Message 7 of 10
(1,279 Views)

@Redzouz1 wrote:

I have looked different topics and couldn't find a proper answer. So far, I have been using a Data Reference stored in a FGV - VI. But, I feel this is so much work and I can't believe there is something much simple similar to other programming languages. 


DVR's are horrible. If they are not initialized they fail. Also, if your stop your main, you can't debug anything, as the DVR stopped to exist.

 

If you have a FGV, why not store the value in it (in stead of a DVR?). The DVR doesn't add anything. 

 

Why not use a normal global? Do make it protected...  Or private, with a protected get and set functions.

Message 8 of 10
(1,263 Views)

Indeed, I thought It will guaranty a memory protection from reading/writing at the same. with non reeantrant FVG it is already the case. Then it is not needed. Thanks for you input

Message 9 of 10
(1,242 Views)

@Redzouz1 wrote:

Indeed, I thought It will guaranty a memory protection from reading/writing at the same. with non reeantrant FVG it is already the case. Then it is not needed. Thanks for you input


Keep in mind that with any global (or actually any data that's not by wire and by value) you can get race conditions.

 

If the global is a cluster a get (from a FGV, DVR or private global) that is changed and then set will be a problem waiting to happen. With a FGV, you could 'merge' the get, change and set. As the get, change and set are always done in the same VI, this works.

 

I agree with @drjdpowell. There might even be more structural solution avoiding the need for this altogether. But we'd need more info.

0 Kudos
Message 10 of 10
(1,232 Views)