billings11 Posted March 5, 2008 Report Share Posted March 5, 2008 I've developed a lot of large labview applications in the past - espescially large test applications. Often I've released an "office edition" of a test application. That is, I've stripped out all the DAQmx, NI-Motion, etc. dependencies from the application and built an executable for managers to run in their offices without the hardware. I retain all the code to save and load tests from a database, do statistical analysis, etc., but remove all the code to actually run tests. This is so a production manager at a factory can view test results and analyze data from their office, and the IT department does not have to be burdened with the painful NI installers for DAQmx, NI-Motion, etc., that are not group policy deployable. All they have to install is a run-time engine. And this way I don't have to write an entirely new project... I can just strip out a couple of cases from my top-level vi's state machine (the ones that involve hardware drivers like DAQmx) and build a new executable. Suddenly I have a version of the exe that doesn't need all those NI dependencies. The last couple applications I developed have a large LVOOP class called "Test". Each test type is a sub-class. A method of each class is "Run Test". But another method of each class is "Analyze Results". All the hardware dependencies come from the "Run Test" method, which I never call in my office edition of the application. But I do call teh "Analyze Results" method. Using LVOOP (LV8.2) in this manner, even though I remove all calls to the "Run Test" method in my code, in order to run a single method of the class I have to load all methods of all inherited classes, including the unused "Run Test". The result is that it's impossible to strip out the DAQmx or NI-Motion content easily simply by never calling it. If it exists as part of the LVOOP class hierarchy it must load all components of all methods, regardless of whether they are being used. Is there any way to easily structure an executable build, or remove select content from a project that will effectively eliminate the need for certain hardware driver requirements in the way I've described above? Quote Link to comment
Justin Goeres Posted March 5, 2008 Report Share Posted March 5, 2008 QUOTE(billings11 @ Mar 4 2008, 11:54 AM) Is there any way to easily structure an executable build, or remove select content from a project that will effectively eliminate the need for certain hardware driver requirements in the way I've described above? One way I've done this for LVOOP-based instrument drivers is to create a "simulation" class as a child of my instrument class. So I would have something like.... MyInstrument.lvclassRead Current Value.vi (dynamic dispatch) [*]MyInstrument (simulated).lvclass (child of MyInstrument.lvclass) Read Current Value.vi (override) The simulated-instrument child class contains only VIs that override hardware-dependent methods in the original class. Back in the main app, I add some logic (probably in a Create Instrument state or some such) that checks a flag to see if it's supposed to be simulating the hardware or not. That flag determines which class instance I use for my instrument: either the "real" one or the simulated one. Then any method calls to the instrument in the app automagically go to the "simulated" instrument methods when necessary. This doesn't give you an exact answer to your problem, but you might be able to do something similar. Bonus: By using this method, you can add Private Data to just the simulated instrument, to track its state and do a better "simulation" of the hardware than you would get by just disabling the offending functionality in the parent class, and it doesn't pollute the design of the original class. Quote Link to comment
Aristos Queue Posted March 5, 2008 Report Share Posted March 5, 2008 Remove the unused child class from your project tree. If it is really unreferenced, it won't load into memory. You can dynamically load the class into memory if you discover that you need that piece of hardware. This is *exactly* the behavior of the Getting Started Window in LV8.5. There's an indepth discussion of this method of programming at the Eyes on VIs blog ( http://eyesonvis.blogspot.com/2006/08/obje...ted-window.html and the next few posts to that blog). Quote Link to comment
billings11 Posted March 6, 2008 Author Report Share Posted March 6, 2008 QUOTE(Justin Goeres @ Mar 4 2008, 03:50 PM) One way I've done this for LVOOP-based instrument drivers is to create a "simulation" class as a child of my instrument class.So I would have something like.... MyInstrument.lvclass Read Current Value.vi (dynamic dispatch) [*]MyInstrument (simulated).lvclass (child of MyInstrument.lvclass) Read Current Value.vi (override) The simulated-instrument child class contains only VIs that override hardware-dependent methods in the original class. Back in the main app, I add some logic (probably in a Create Instrument state or some such) that checks a flag to see if it's supposed to be simulating the hardware or not. That flag determines which class instance I use for my instrument: either the "real" one or the simulated one. Then any method calls to the instrument in the app automagically go to the "simulated" instrument methods when necessary.This doesn't give you an exact answer to your problem, but you might be able to do something similar.Bonus: By using this method, you can add Private Data to just the simulated instrument, to track its state and do a better "simulation" of the hardware than you would get by just disabling the offending functionality in the parent class, and it doesn't pollute the design of the original class. But here is my situation. All my hardware I/O is contained in my "Run Test" method. Even if I never call "run test", the exe is trying to load all the vi's beneath it. I've already deleted all instances where I call the "Run Test" method. But the exe still asks for all the DAQmx and NI Motion dependencies! It seems like it runs similar to the way it does in development mode - if I try to open one small method of a sub-class with no sub-vi's, it still loads 1000+ vi's from all dependencies of all methods of the entire LVOOP class hierarchy.So it seems like even if I create a method called "simulated Run Test", if "Run Test" is still present in the class hierarchy (even though I'm never calling it) it is going to try to load its dependencies. It seems like the only way to do it would be do delete the "Run Test" method entirely from the LVOOP hierarchy, or to go in each Run Test method and disable any hardware functions.So do your simulated instrument and regular instrument classes inherit from the same place? It seems like if they are part of the same class hierarchy the exe will load all the regular instrument class vi's even if you are only using your simulated instrument class.QUOTE(Aristos Queue @ Mar 4 2008, 06:55 PM) Remove the unused child class from your project tree. If it is really unreferenced, it won't load into memory. You can dynamically load the class into memory if you discover that you need that piece of hardware. This is *exactly* the behavior of the Getting Started Window in LV8.5. There's an indepth discussion of this method of programming at the Eyes on VIs blog ( and the next few posts to that blog). Aristos,Its unfortunately not a single child class, but instead a single method of all child classes. Quote Link to comment
Omar Mussa Posted March 6, 2008 Report Share Posted March 6, 2008 QUOTE(billings11 @ Mar 5 2008, 02:55 PM) Aristos,Its unfortunately not a single child class, but instead a single method of all child classes. I have the same issue AQ -- would adding 'Conditional Disable' structures work? -- I know that you can set a conditional disable based on a custom project conditional disable symbols (Project-->Properties) but I haven't tried to check whether this will affect the build dependencies. Quote Link to comment
Aristos Queue Posted March 6, 2008 Report Share Posted March 6, 2008 QUOTE(Omar Mussa @ Mar 5 2008, 06:01 PM) I have the same issue AQ -- would adding 'Conditional Disable' structures work? -- I know that you can set a conditional disable based on a custom project conditional disable symbols (Project-->Properties) but I haven't tried to check whether this will affect the build dependencies. Conditional disable structures do change build dependencies. Any commented out subVI will not be included assuming there are no other references to those subVIs elsewhere. Unfortunately, in the case of LVClasses, the class itself is a reference to all of its member VIs. When a class is built into a built app, the entire class gets built in, even if all of the methods are not necessarily invoked. That's the behavior because of the very common pattern of dynamically loading classes into memory, classes that might use methods of the parent that aren't otherwise invoked, and they'll expect those VIs to be there. If you don't want certain member VIs to load into memory, you're going to need to remove those VIs from the class in some fashion. The easiest method I can suggest is to have a member VI that loads the desired VI into memory and returns a VI Refnum. You override that loader VI in each class and have it load the functionality particular to that class. There are other methods more creative, but that's the easy one to point to. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.