From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Automagically Run Dynamic Dispatch VIs

Solved!
Go to solution

Hi,

 

I'm developing an API for several customers.  All customers get the same methods, but the prototypes and implementations might be different.  I have a method loader that looks like this:

 

Loader.png

 

The method loader dispatches the customer-specific prototype based on the customer's class that I load from configuration.  While there's nothing wrong with this loader, I'd really like to get away from "one state per method" because I have hundreds of methods to expose.  I have a standard name prefix for all command prototypes and implementations, so I'd like to load them from disk.  I'd like to avoid one class per method.  I'd like something like this:

 

Ideal_Loader.png

 

Which appears to be unsupported in LabVIEW 2015.  Does anyone know of a supported way to skin this cat?

 

Thanks for taking a look,

 

Steve K

0 Kudos
Message 1 of 29
(5,795 Views)
I'm sorry but I have to admit that I have no idea what this code is trying to accomplish. You refer to the top snippet as a method loader, but it isn't loading anything. It is iterating through thirty some odd dynamic dispatch (?) VIs that do something unspecified internally and return some unspecified value that is accumulated into an array.

The bottom code has a broken wire because you don't have anything wired to the open to define the connector pane. But even if you did, it still might not work if the input to the VI being called is a dynamic dispatch VI.

You say each customer gets the same methods, but the implementations and prototypes are different. What do you mean by prototypes? LabVIEW doesn't do prototypes.

Frankly, all this sounds like you are trying to force fit something inherited from some other language into LabVIEW.

Mike...

Certified Professional Instructor
Certified LabVIEW Architect
LabVIEW Champion

"... after all, He's not a tame lion..."

For help with grief and grieving.
0 Kudos
Message 2 of 29
(5,764 Views)

I think the terms "dynamic dispatch" and "automagical" are misplaced here.

 

If the developer choses a correct OOD, the OOP implementation of dynamic dispatch already solves everything you want to except one: Connector panes must be identical (except calls input/outpu) for all VIs in on "dynamic dispatch tree".

That being said, the issue to solve is to get a generic connector pane (parameters.... i assume that this is what the OP calls "prototype"). The only solution is using flexible datatypes as LV OOP doesn't allow overloading and polymorphism for dynamic dispatching. There are two datatypes usable for this:

- Variant

- Class

 

Both have their advantages and disadvantages each, so please investigate which one is more suitable for your requirements.

 

Norbert


EDIT: Automagical reminds me of unicorns.... anyone else having that weird association?

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
0 Kudos
Message 3 of 29
(5,751 Views)

Thanks for taking a look.  I appreciate your time and questions.

 

The generic problem I'm trying to solve is, "how do I run dynamic dispatch VIs from disk?"

 

"...but it isn't loading anything..."

IMHO, who knows what it's doing?  It might be shining shoes.  Calling it a method loader was too specific out of context, I'm sorry.  My framework ingests references and spits out an API.  I called it a method loader exactly because my references are "...accumulated into an array."  This array then defines my methods for my customer.  ...Yea, that was confusing for sure!

 

On that note, "...the issue to solve is to get a generic connector pane..." is not my issue.  I have identical connector panes, the output type is strict, native, and what's required downstream.

 

"The bottom code has a broken wire because you don't have anything wired to the open to define the connector pane."

I browsed to the prototype of this VI.  I wired the class into the dynamic dispatch terminal.  It's broken because, to use NI's words, "The Call By Reference node does not support dynamic member VIs in this version of LabVIEW" (2015).

 

"...it still might not work if the input to the VI being called is a dynamic dispatch VI."

Agreed, that's the problem I'm trying to solve.  I want to load a dynamic dispatch VI from disk and run it, while retaining the benefits of LVOOP, because I might want to override one of these.

 

untitled.png@Norbert_B

 

Thanks again!!!

 

-Steve K

0 Kudos
Message 4 of 29
(5,727 Views)

Steve,

 

you are familiar with LVOOP based plugin architectures using "Get LV Class Default Value.vi"?

If not, this is what you are looking for....

 

Norbert

 

PS: Nice unicorn

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
0 Kudos
Message 5 of 29
(5,718 Views)

Thanks Norbert,

 

Way, way, (way) upstream we use a similar technique to load the class for Customer X.  That part works.

 

Now, (and again, my work-around is OK), each customer's class has the same method names <standard prefix + method name>.vi, but different implementations.  I want to grind through all <standard prefix + method name>.vis, let LVOOP dispatch whatever VI is (or is not, i.e. run the parent) defined for Customer X, and do so without hard-coding each VI in a sequential state machine.

 

The VI server approach would be exactly what I want; but if I make the class terminal static then I can't dynamically dispatch Customer X.

 

Thanks for sticking with me.

 

-Steve K

0 Kudos
Message 6 of 29
(5,709 Views)

I'm not sure if i understand what you are saying.... however, this is the approach that works:

HAL Dynamic Dispatch.PNG

 

Key is INHERITANCE of LV classes....

 

Norbert

 

EDIT: In case you are wondering: The class functions are from the parent class... however, during runtime, child classes are loaded and the dynamic dispatch overrides will execute. If no override for that specific child class exists, the parent method will execute.

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
0 Kudos
Message 7 of 29
(5,706 Views)

Exactly!

 

In that picture, imagine that instead of INIT.vi, all plugins could have the following dynamic dispatch VIs:

 

  1. INIT_001.vi
  2. INIT_002.vi
  3. ...

300.  INIT_300.vi

 

That's basically what I'm working with.  In LabVIEW, I have to put INIT_001.vi through INIT_300.vi on the BD if I want to override them.  That's exactly what I'm doing with my "method loader", but it feels silly.  I'd rather load the collection of INITs from disk, based on their file name, and dispatch them automagically.  I feel like we're getting close to sharing understanding.  IMO, it's OK if the answer is:

 

download.jpg

 

-Steve K

0 Kudos
Message 8 of 29
(5,691 Views)

@Pie566942.0 wrote:
[...]I feel like we're getting close to sharing understanding. [...]

Of that, i am not convinced...

I think you are talking about 300 classes. One class with 300 different inits is pure misdesign and should be scrapped immediatly.

Handling 300 child classes can be challenging, but it is doable. Having 300 different inits per class is not doable.

 

Norbert

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
0 Kudos
Message 9 of 29
(5,681 Views)

Hi Norbert,

 

I appreciate your enthusiasm.  I agree that there should be "an" initialization VI per plugin.  However, this is not an initialization VI.  I was using the picture you posted (arrow pointed to INIT) to clarify what I'm after.  Let's bring the specific context of my question back into consideration.

 

My "INIT" VIs are actually Cmd_def_<command_name>.vis.  Each Cmd_def VI exports a method to my customer.  I'm exporting a few hundred methods.  This is a tool.  In my original post I wrote, "I'd like to avoid one class per method."  One class per method is too much time and overhead compared to "adding a state to a sequential state machine."

 

In your opinion, is one class with 300 methods not doable?

 

-Steve K

0 Kudos
Message 10 of 29
(5,670 Views)