LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Read Data Value Reference (DVR) value dynamically during run-time

Is there a low-level way to read a the DVR's data without knowing the structure of the data and just determining it at run-time? Maybe as a variant? I'm using LV 2018.

 

I would like a generic way of serialising objects that use a DVR as their private data so that I can write it to a JSON file with a key name format of my choosing. I can't use inheritance and override a "To JSON" method as the classes are already inheriting from something else which wouldn't always be appropriate to have this abstract method. The LabVIEW version I am using does not support interfaces directly.

 

Conversion to XML seems to work well for class hierarchy, but it does not dereference the DVR and just returns the 32-bit handle.



Using LV2018 32 bit

Highly recommended open source screen capture software (useful for bug reports).

https://getsharex.com/
0 Kudos
Message 1 of 12
(1,494 Views)

Hi Matt,

 

Unless your DVR already contains a variant at creation (which could be a bit impractical and inefficient to use), there is no official way to dereference a DVR without statically knowing its data structure. If you experiment by casting e.g. a cluster DVR to a U32, then to a string DVR to try getting the raw data, that leads to undefined behaviors such as crashes.

 

Your best option is for your classes to have a public method e.g. "Get Data" to return the dereferenced data. You could then programmatically call this accessor using VI server and proceed with the generic serialization. You will also need a "Set Data" method if you want to deserialize. A disadvantage of this is that by exposing the private data publically, you are "breaking" the encapsulation principle of OOP...

 

Regards,

Raphaël.

Message 2 of 12
(1,452 Views)

@raphschru wrote:

Hi Matt,

 

Unless your DVR already contains a variant at creation (which could be a bit impractical and inefficient to use), there is no official way to dereference a DVR without statically knowing its data structure. If you experiment by casting e.g. a cluster DVR to a U32, then to a string DVR to try getting the raw data, that leads to undefined behaviors such as crashes.

 

Your best option is for your classes to have a public method e.g. "Get Data" to return the dereferenced data. You could then programmatically call this accessor using VI server and proceed with the generic serialization. You will also need a "Set Data" method if you want to deserialize. A disadvantage of this is that by exposing the private data publically, you are "breaking" the encapsulation principle of OOP...


If you have a class that manages general data, for instance for keeping an data store with run time defined data types, not exposing the private data in some way will make it useless.

 

There's no way a class will be able to get\set a I32 without exposing the I32...

 

It's a major improvement to exposing the DVR (as a variant?) and than trying to get it's data.

 

In this specific case, you could give each class it's own "To JSON" method. Of course, doing so violates the "Single-responsibility principle".

0 Kudos
Message 3 of 12
(1,438 Views)

Thanks for the suggestions. I had another look and found the DVR refnum type which may have done what I wanted, but couldn't find a way of generating a valid one. Guess I'll go back to a class based approach for now and call it dynamically if the connector pane signature matches.



Using LV2018 32 bit

Highly recommended open source screen capture software (useful for bug reports).

https://getsharex.com/
0 Kudos
Message 4 of 12
(1,355 Views)

@matt.baker wrote:

Thanks for the suggestions. I had another look and found the DVR refnum type which may have done what I wanted, but couldn't find a way of generating a valid one.


Getting the type of a DVR refnum is trivial...

 

You can't (easily) generate a DVR with a dynamic type at run time. You can make a .vim that generates the type of a DVR at compile time.

 


@matt.baker wrote:

Guess I'll go back to a class based approach for now


You mean go forward 😋.

 


@matt.baker wrote:

 and call it dynamically if the connector pane signature matches.


That sounds questionable.

 

Seems like you'd want to use polymorphism (e.g. dynamic dispatching) to automatically do that. Or is that what you mend?

0 Kudos
Message 5 of 12
(1,347 Views)

 


@matt.baker wrote:

 and call it dynamically if the connector pane signature matches.


That sounds questionable.

 

Seems like you'd want to use polymorphism (e.g. dynamic dispatching) to automatically do that. Or is that what you mend?


He explained why: "I can't use inheritance and override a "To JSON" method as the classes are already inheriting from something else which wouldn't always be appropriate to have this abstract method. The LabVIEW version I am using does not support interfaces directly."

0 Kudos
Message 6 of 12
(1,342 Views)

@raphschru wrote:

 


@matt.baker wrote:

 and call it dynamically if the connector pane signature matches.


That sounds questionable.

 

Seems like you'd want to use polymorphism (e.g. dynamic dispatching) to automatically do that. Or is that what you mend?


He explained why: "I can't use inheritance and override a "To JSON" method as the classes are already inheriting from something else which wouldn't always be appropriate to have this abstract method. The LabVIEW version I am using does not support interfaces directly."


So in stead of creating an inappropriate (?) abstract method that would work well, you'd prefer matching the connector pane signatures? Wouldn't that require you to go through project scripting (to find the object's VI) and than VI Server (to get the CP)?

 

I just don't see how that would be an improvement, but I'm intrigued.

 

I guess the question is why it's that inappropriate to give a (each) class that needs to be serialized to JSON a 'to JSON' method (yes srp, I know). I do avoid that by having serialization code that takes any object. But I don't use DVRs. For a list of other reasons, I'll add this one.

0 Kudos
Message 7 of 12
(1,334 Views)

 

wiebe@CARYA wrote:



So instead of creating an inappropriate (?) abstract method that would work well, you'd prefer matching the connector pane signatures? Wouldn't that require you to go through project scripting (to find the object's VI) and than VI Server (to get the CP)?

This is much simpler than you think:

raphschru_0-1694518059458.png

You could add a bit of error handling to return meaningful error description when the VI does not exist or does not match the generic connector pane. Also the class terminals of the called VI must be of the generic class "Object", otherwise it won't match.

 

 

Also a specific implementation of "Get DVR Data.vi" would look like this:

raphschru_0-1694519393254.png

 

wiebe@CARYA wrote:

I just don't see how that would be an improvement, but I'm intrigued.

This is not an improvement, this is an implementation of an interface mechanism, which is not present natively in LV2018.

 

 

Regards,

Raphaël.

0 Kudos
Message 8 of 12
(1,309 Views)

@raphschru wrote:

 

wiebe@CARYA wrote:



So instead of creating an inappropriate (?) abstract method that would work well, you'd prefer matching the connector pane signatures? Wouldn't that require you to go through project scripting (to find the object's VI) and than VI Server (to get the CP)?

This is much simpler than you think:

raphschru_0-1694518059458.png

You could add a bit of error handling to return meaningful error description when the VI does not exist or does not match the generic connector pane. Also the class terminals of the called VI must be of the generic class "Object", otherwise it won't match.

 


It's is a little simpler than I though, but not much...

 

I'm missing the part where the connector pane signature is compared... I suppose that would be used to convert a specific DVR type to the variant.

 


@raphschru wrote:

Also a specific implementation of "Get DVR Data.vi" would look like this:

raphschru_0-1694519393254.png


The input class would be a DD input. The to more specific wouldn't be required.

 

If to more specific is required, unbundling wouldn't be allowed.

 

You'd still have to implement this "Get DVR Data.vi" method for each class with a DVR. Why not convert to JSON right there and then.

 


@raphschru wrote:

wiebe@CARYA wrote:

I just don't see how that would be an improvement, but I'm intrigued.

This is not an improvement, this is an implementation of an interface mechanism, which is not present natively in LV2018.


If it isn't an improvement, why use it?

0 Kudos
Message 9 of 12
(1,282 Views)

I didn't like the idea of using a generic object type for the inputs for each of the To JSON methods, so I created the following monstrosity instead:

To JSON.png

 

 

It finds the matching class member using the Application -> LabVIEW Class -> All Methods Of LVClass method, populates the nearest matching terminals on the connector pane, runs the VI and collects the outputs.



Using LV2018 32 bit

Highly recommended open source screen capture software (useful for bug reports).

https://getsharex.com/
0 Kudos
Message 10 of 12
(1,266 Views)