08-15-2025 05:33 AM
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:
How to properly structure the action input so that multiple class instances can maintain independent FGV-like state.
Ensuring thread safety when multiple VIs access the class simultaneously.
Best practices for initializing the data inside the class (similar to FGV Init
).
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!
08-15-2025 07:19 AM
@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:
Bob Schor
08-15-2025 07:29 AM
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 ...?
08-19-2025 02:15 AM
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.
08-26-2025 09:27 AM
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
And also the write and read accessors (write top, read bottom)
Please have a look on the project view of the locations of the classes and FGV, perhaps this is also wrong approach.
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.
08-26-2025 01:17 PM
@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":
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.