Mass Compilers

cancel
Showing results for 
Search instead for 
Did you mean: 

LVOOP with dynamic loading of DLL

We have legacy LV test code that talks to one of our products using USB and a custom DLL API (C-style function calls).  Now I have to modify the code to support a new version of the product that uses a different custom DLL.  I'll have the operator identify at start-up which version of the product he's testing.  I do not want both DLLs loaded at the same time because each is large and is a CPU hog even when idling.

I could write a library of VIs using Case structures and VI Server calls.  But I've learned a lot of LVOOP details in recent group meetings, and I think LVOOP would be more elegant.  I'm a little fuzzy on the optimum implementation details given the restriction that only one DLL can be loaded.

Any recommendations?  Thanks.   -Joe Czapski

Joe Czapski
Automation Software & Instrumentation Engineer
Thermo Fisher Scientific
Tewksbury, Mass.
0 Kudos
Message 1 of 6
(9,744 Views)

Hi Joe,

It sounds like the factory pattern could solve this problem for you.  You would create an abstract parent class that would represent a generic DLL, and then concrete children classes for each of the actual DLL types that you have.  You can use the abstract parent level DLL class in your code, and use an object factory to load the correct concrete child at runtime.  This is exactly what I did in that sample code I posted, just replace "DMM" with "DLL" and you should be off to a good start.

https://decibel.ni.com/content/docs/DOC-32704

EDIT: Forgot to ask, how much overlap is there functionally between the two DLL's? 

-Jon

0 Kudos
Message 2 of 6
(5,712 Views)

I agree with Jon's assessment. However with DLLs you need to go through a few extra hoops if you're trying to avoid keeping both in memory at the same time. Proper use of the factory pattern will ensure this, but to be explicit:

Basically if either of your classes are statically linked to their respective DLLs-- that is where you configure the DLL name/path via the code interface node dialog box (opposed to a path on the block diagram)-- then as soon as you use an object of that class your DLL will be loaded if it isn't already. This means while using the factory you need to be extra careful to only operate on the objects from the parent class level. Never use specific implementations of the parent class: if you slap a constant of either of the child classes anywhere on a diagram of your main application's VI hierarchy, it will force that class into memory from the time the application is loaded and the respective DLL will come along for the ride automatically. Have your factory load the child classes dynamically without ever being aware of their actual type and you should be good. Never operate on those objects being aware of their type.

Finally, I'm unclear on how LabVIEW handles unloading DLLs which are statically linked if your code has to swap out versions at run-time. Is swapping versions on the fly something you have to do?

Message 3 of 6
(5,712 Views)

Thanks very much for the helpful replies.  It would be nice to swap versions of the product-under-test on the fly, but it's not necessary.  The products are tested in batches of the same version.  I don't mind making the operator exit and restart the app between batches, at most twice a day.  Anyway LabVIEW seems to require a complete exit in order to fully unload a DLL.

The two different DLLs are 90% functionally equivalent, so OOP inheritance is a nice solution.

-Joe Czapski

Joe Czapski
Automation Software & Instrumentation Engineer
Thermo Fisher Scientific
Tewksbury, Mass.
0 Kudos
Message 4 of 6
(5,712 Views)

You can load/unload a DLL if you specify the path on the block diagram. If a CIN is called with a path different than on it's last call, the previous DLL will be unloaded and the new one loaded in. If supplied with an empty path, the previous one will be unloade and nothing loaded to replace it. It becomes a bit more hairy if you have multiple CINs making calls to the same DLL, but in theory you should be able to unload...

Message 5 of 6
(5,712 Views)

It worked!  kegghead, thanks for the tip of using 'Get LV Class Default Value' instead of placing child class constants on the diagram.

I specify the DLL in the Call Library Function Node configuration instead of passing the DLL path in.  I tried hiding one of the DLLs on disk as an experiment.  If I open the top-level VI from the project, then it has a broken arrow and says that it can't execute because a dynamic-override child can't execute.  However, if I open the top-level VI from disk without any project open, then it can execute.  If I select the child class that doesn't use the hidden DLL, it executes without error.  But if I select the child requiring the hidden DLL, it pops up a window searching for the DLL.

-Joe Czapski

Joe Czapski
Automation Software & Instrumentation Engineer
Thermo Fisher Scientific
Tewksbury, Mass.
Message 6 of 6
(5,712 Views)