LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Using a VI explicity and as a subpanel in the same code?

I realize this message is somewhat long, so skip to the bold portion if you are faint of heart.

I am attempting to use a Subpanel (for the first time) to simplify maintenance and compiling of my application.  A subpanel should allow me to only have to build one executable that behaves in different ways, rather than building separate executables which is what I have done in the past.  This is time consuming and prone to error, so I was really hoping subpanels would be the easy answer.  I have read nearly all posts pertaining to subpanels, but I still can't get my head completely around the concept.

I have a VI that I want to display/run normally when the application is configured in non-emulation mode (via config file), but I want to display the same VI as a subpanel of another "wrapper" VI if the application is configured in emulation mode.  The "wrapper" VI simply contains boolean buttons that simulate physical buttons on a real device.  The VI will not be used in both ways at the same time, just whichever mode it is configured for.

My attempt at this has been to create a case structure in which the FALSE case calls the SubVI directly (placed statically on the block diagram), and the TRUE case calls a different VI (the wrapper) that has a subpanel containing the SubVI.  It doesn't seem to be a problem getting the SubVI to display in the subpanel, but the RunVI invoke method on SubVI fails with "Error 1000: The VI is not in a state compatible with this operation."  I suspect this is due to the fact that the VI is loaded in memory already (from the static placement) somehow.  But as long as the VI isn't running before I invoke the RunVI method (which it won't be), why won't it work?

What is the best way to accomplish what I need?  I know there are a few things I can try (such as making it re-entrant or making all calls to SubVI dynamic), but they all seem to have their own downfalls.

Thank you in advance,

Phish ><>
0 Kudos
Message 1 of 5
(2,818 Views)
That's expected behavior. If you look at the execution state of your subVI when you create a reference to it in your wrapper VI you will see that it says "Running" since it's loaded in memory. Hence the error.

What downsides do you see to loading the subVI dynamically using the VI server?
0 Kudos
Message 2 of 5
(2,805 Views)

If I use the VI dynamically, I'll have to explicitly include it in builds, have to manually load it to do a mass compile and/or save (which is often since some code is shared between Windows and Linux devices).  And I'm just speculating here, but I suspect debugging the application will become much more difficult if the VI is run dynamically.  Then there's the fact that I'll have to use some slightly kludgy code to build a path to the VI for a reference.

No show stoppers there, but the whole idea was to make the code easier to maintain.  While I think that that will improve things a lot, it's also a step backwards.

BTW, I tried setting the SubVI to reentrant and it worked for the most part.  It could be run statically or dynamically (using RunVI and a subpanel).  However, when running statically, I could not get its event structure to respond to keypresses.

0 Kudos
Message 3 of 5
(2,789 Views)
That, unfortunately, is also expected behavior. Reentrancy is not something that's meant to be used with VIs that have a user interface. Reentrancy allows you to have more than one instance of a VI running in memory. When you have the VI's panel open, how do you know which instance you are looking at? You don't.

I don't think there's any magic bullet solution for you, and it seems that based on what you want to do you will need to load the subVI dynamically. What "kludgy" code would you need to write? Besides, aren't you already doing that in the wrapper VI? I would think that you really only need to write the code once and use it as a subVI to get the path for each of your interested subVIs.

Message Edited by smercurio_fc on 03-10-2006 11:30 AM

0 Kudos
Message 4 of 5
(2,782 Views)
I agree that reentrancy isn't the best answer.  And in my case, it isn't an answer at all since keypresses aren't dealt with.

In my WrapperVI, I was passing the SubVI name as a string to the Open VI Reference.  Since, at the time, I had the SubVI statically placed in the MainVI, it was loaded into memory already.

So I guess you are right:  I will not be able to do it that way and I'll need to open the reference with a path at both points in code (where I call the SubVI directly, and where I call it in the WrapperVI).  That is where the "unclean" code is going to come in.  I'll have to use two comepletely different, non-correlating paths depending on whether I'm running the code in the development system or in the run-time engine.  I do have a VI that I use to properly determine the path to the top-level VI whether it be in an LLB/EXE or not, but that won't keep me from having to use some hard-coded paths.  I hate hard-coded paths.

I'll try it out and experiment some.  Thank you for your help so far.
0 Kudos
Message 5 of 5
(2,773 Views)