When Should the ‘To More Specific’ or ‘Preserve Tun-Time Class’ Primitives be Used with OOP in LabVIEW?


Today’s entry was inspired by a question I recently received from someone while presenting at Developer Days in Salt Lake City – I was asked, “when and why should I use the ‘preserve run-time class’ node, and what’s the difference between it and the ‘to more specific’ primitive?” It was a good question, and something that I didn’t fully understand myself until I spent some serious time doing object-oriented programming. What follows is my attempt to explain this for anyone else who might have ever wondered the same thing.

The ‘to more specific’ node is a mechanism to tell the LabVIEW compiler that an object is guaranteed to belong to a certain class of objects.  Without this assurance, the compiler has no way of knowing what the object belongs to or is capable of at compile time, and would therefore show a broken wire if you attempted to pass the object wire into a function that can only act upon a certain class of objects.

Perhaps the most common illustration of this is a plug-in framework using classes (also known as a factory pattern).  A factory pattern enables you to add or change functionality simply by loading a new child class at run-time.  It is required that the calling application already have in memory a common parent, but the newly loaded child class can then override or extend the behavior of dynamically dispatched methods.  As an example, a framework may already be written to act upon a generic measurement, which has methods to initialize, acquire and analyze a signal.  A specific measurement, such as a frequency sweep, could redefine the implementation of these methods.

Shown below is the code required to load a specific measurement at run-time.  The ‘Get LV Class Default Value.vi’ brings a class into memory from a location on disk, but the compiler has no way of knowing the type of object prior to this operation.  This is why we use the ‘to more specific class’ node, which then allows us to treat the object as belonging to a specific hierarchy – in this case, we treat it as a measurement.  Note that the error handling is designed such that we only add the loaded class to the array if it is a valid member of that class hierarchy.  If we had not handled this correctly, and we attempted to load an invalid class, this node would return the parent ‘Measurement.lvclass’ object.

A.png

The ‘preserve run-time class’ node is also a way to give the LabVIEW compiler a guarantee that it would not otherwise have at compile-time – in this case, we are telling the compiler exactly what class of object will be passed out.  The primary use-case for this node is within a VI that has a dynamic input terminal and a dynamic output terminal for the same class, but there is not a guarantee that the object’s class will be preserved between them.  If, for example, we are dynamically loading an object that will replace the object that was passed into the VI, the compiler has no way to know what class the object will be, and will therefore have a broken arrow.  ‘To more specific’ cannot be used in this case, as we need to guarantee the exact class of the object.

In the example below, the other case of the case structure is set to ‘Use Default’ for the class wire, which means that LabVIEW does not know at compile-time what the class of object is that it will receive. The first diagram of ‘common.vi’ attempts to use ‘to more specific’ to indicate that the object will be a child of ‘Hardware.lvclass,’ but it still does not guarantee that it will be ‘SCOPE.lvclass.’  As a result, the calling VI, initialize.vi, which has dynamic input and output terminals, is broken, as it needs to know that the exact same class of object will be passed between.

B.png

The diagram below shows how we use ‘preserve run-time class’ to guarantee that the class of the object will be the same as it receives.  As a result, initialize.vi can compile and we no longer see a broken run arrow.

C.png

This illustrates the most common and important use case for ‘preserve run-time class.’

As always, you can find more information on these in the LabVIEW help, but free to post questions and comments!

Eli

Advertisements

One thought on “When Should the ‘To More Specific’ or ‘Preserve Tun-Time Class’ Primitives be Used with OOP in LabVIEW?

  1. If, at run time, LabVIEW detects that you wired a child class object to a subVI that expects a parent class object, LabVIEW can downcast the subVI output to a child class object automatically. Automatic downcasting does not require you to use the To More Specific Class function. However, automatic downcasting can occur only if LabVIEW can guarantee that the class object you wire to the subVI is compatible with the input the subVI expects. For example, if you store a class object in a variant and wire the variant data to a subVI, LabVIEW cannot guarantee that the subVI contains data that belongs to the same class as the data the variant originally stored. To help LabVIEW check that the class object you wire to the subVI is compatible with the class object the subVI expects, use the Preserve Run-Time Class function. If the two objects are incompatible, the function returns an error and sets the class of the output data to the parent class the subVI expects. You also can use this function with data value references . The Data Value Reference Read / Write Element border node must preserve run-time type. You can use the Preserve Run-Time Class function to check that the class object you wire to the Data Value Reference Write node is compatible with the class object you wired to the Data Value Reference Read border node.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s