LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

FGV and Class Object

Hello LabVIEW community,

I am trying to implement a Functional Global Variable (FGV) pattern inside a LabVIEW Class (LVOOP) for better encapsulation and maintainability.

What I have so far:

  • A class with private data (similar to what the FGV shift register would store)

  • Case structure for actions: Init, Read, Write inside class methods

  • Trying to maintain the same behaviour as a traditional FGV

Problems I am facing:

  1. How to properly structure the action input so that multiple class instances can maintain independent FGV-like state.

  2. Ensuring thread safety when multiple VIs access the class simultaneously.

  3. Best practices for initializing the data inside the class (similar to FGV Init).

  4. Error message given by Write accessor : "Front Panel Terminal 'Device out': Run-time type not propagated from dynamic input to dynamic output"

My questions:

  • Has anyone successfully implemented FGV inside a LabVIEW class?

  • Can you provide an example or template of how to wire the shift-register + action case structure within a class method?

  • Any pitfalls or recommendations when replacing traditional FGVs with class-based encapsulation?

I have attached my simple FGV as well as example of accessor for one of the class members.

 

Thank you in advance for any guidance or example VIs!

0 Kudos
Message 1 of 6
(295 Views)

@bialku wrote:

I have attached my simple FGV as well as example of accessor for one of the class members.

Thank you in advance for any guidance or example VIs!


No, you attached nothing.

 

To get the most "helpful" Help, I suggest that you do the following:

  1. Make a simple Project (call it "FGV Class Demo" or something similar).
  2. Inside the Project, create an FGV Class and the Methods (Init, Read, Write, etc.) that you want.
  3. Also include a Test routine that uses this class.
  4. Realizing that almost all new LabVIEW "students" (probably yourself, included) are using the latest version of LabVIEW, but many seasoned LabVIEW developers providing help in the LabVIEW Forums are running LabVIEW 2019 or 2021, please do a "Save for Previous Version" for your Project, and specify LabVIEW 2019 or 2021.
  5. This will produce a folder that has your Project and possibly a lot more stuff.  Try to find the folder with your Project.  Once you do, righfoldet-click the Project folder, and use the "Send to:" option "Compressed (zipped) folder.
  6. Attach that zipped folder.  We'll download it, unzip it, and check out your code.  You should get helpful suggestions, as many of us love to teach/help new LabVIEW users get started.

Bob Schor

0 Kudos
Message 2 of 6
(263 Views)

My first reaction was: The FGV does not belong inside the class. Instead use the class as a kind of FGV. 

But then I realized I don't know what you are trying to do. How do you want to use this FGV in a class?

 

Do you

- want to exchange one or more values between different objects of the class?

- want to use the values in different places of your application without using the class wires?

- want to ...?

 

 

0 Kudos
Message 3 of 6
(253 Views)

Just as Uli says, an FGV inside a class makes IMHO very little sense. Maybe your special use case is sensible but generally, FGVs were a way of trying to manage common operations on a global set of data before there were classes. Basically it is a poor mans class replacement but only really for singleton objects without a lot of extra internal overhead. In fact it is simpler to create a singleton on a FGV (the FGV is the singleton), than with a proper LabVIEW class. But that is about the only advantage I see about an FGV nowadays.

 

Still I would probably never marry an FGV with a LabVIEW class. I still sometimes use FGVs for quick and dirty tests and throw away tools when needing a singleton, but when designing for larger applications FGVs rather sooner than later tend to create a serious liability in terms of maintaining and testing the application.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 4 of 6
(162 Views)

Hi everyone,

 

Thank you for your replies!

Just came back from holiday, hence why there was no action from myself.

The below is my FGV - which I did not attach previously - still learning

 

bialku_0-1756217273422.png

And also the write and read accessors (write top, read bottom)

Accessors.png

Please have a look on the project view of the locations of the classes and FGV, perhaps this is also wrong approach.

 

Accessors.png

I understand perhaps starting with simple project to master this is the better way, but because this is kind of the addition to this project and I am on the clock in here under pressure, hoping to be put on the correct track by experienced users. Possibly I should not use the classes for this, although wanted to use OOP approach and changing this would have major impact on delivering this within already extended time. If you think it cannot be done in reasonable manner and have to change the way I tackle this then my bad and will have to add this extra time to get rid off the classes etc. 

 

Please allow my lack of competence, still learning, but improvement is on it's way.

Thanks again for your time on this anyway, much appreciated.

0 Kudos
Message 5 of 6
(103 Views)

@bialku wrote:

Hi everyone,

 

Thank you for your replies!

Just came back from holiday, hence why there was no action from myself.

The below is my FGV - which I did not attach previously - still learning

 


When the forum says "Attach", we generally mean "Attach the actual files as .VI, .lvclass, .ctl" files, not just taking screenshots of them.  It's also generally best to save them back to 2020 or so since a lot of forum members stay on old versions.

 

That said, what you're trying to do may well be possible, but the reason WHY you feel like you need to do things this way as well as why you feel that making them class-based is important is still unclear.  I would suggest backing up and posting all that information first so we can either fully understand what you're asking and legitimately help out, or say why exactly that you're doing something completely bonkers.

 

As for your initial error about "Run-time type not propagated from dynamic input to dynamic output":

Kyle97330_1-1756231646852.png

 

Look at the above image.  The way OOP works in LabVIEW is that when you have a "Dynamic dispatch" VI (meaning one that is a class member that can be overridden by a descendant of the class), it must be LITERALLY IMPOSSIBLE for the class TYPE to change.  The data of the class can change, the instance of it can change, but the type absolutely cannot.  Because of this, LabVIEW looks for any code that could POSSIBLY cause a class change, and if it finds it, you get the error message you saw.

 

The two ways to avoid this problem are:

1. Always connect the same class wire that enters through a "Dynamic dispatch" input to a "Dynamic Dispatch" output.  Note that LabVIEW checks for this "sameness" through subVIs, no matter how nested they are.

2. If you think you need to replace the class wire somehow (rare, but possible) then you have to use the "Preserve run-time class" node to forcibly coerce any class to the class on the Dynamic Dispatch wire, which can and will discard class data if you use a class that doesn't work with it.

 

Now, what you're doing ("writing" a class to the wire) is not how Dynamic Dispatch works.  You can probably "fix" the error by changing the terminals on the VI connection pane to not be DD, but if we go back to my original point, I think there's a good chance you  don't fully understand how LabVIEW OOP works and are trying to do something bonkers, but you really really need to explain your motivation and architecture goals to us, not just show us error messages.

0 Kudos
Message 6 of 6
(80 Views)