LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Using static VI references in an application

Solved!
Go to solution

This is the text I see in the Help for the "Run VI" method of the Invoke node:

 

"If TRUE, the referenced VI transfers ownership of the reference from the calling VI to the VI that is running. This means LabVIEW disposes of the reference, along with the parallel data space, when the target VI goes idle, not when the VI that opened the reference goes idle. The reference can still be used by the calling VI until the target VI closes the reference. The calling VI does not need to close the reference unless the Run VImethod returns an error. If the calling VI does close the reference, the target VI can abort and leave memory. If FALSE, LabVIEW automatically disposes of the VI reference when the VI that opened it goes idle. The default is FALSE.

Note  If Auto Dispose Ref is TRUE and the method returns an error, LabVIEW does not transfer ownership of the reference to the target VI. LabVIEW will not automatically dispose of the reference when the target VI goes idle."

 

Thus my concern regarding having to dispose of the reference if the method returns an error.  Also, the above says if the calling VI closes the reference, the target VI "can" abort; is this a warning that it might happen by accident or automatically?  Or is it more of a "the target VI is then enabled to abort and leave memory if it wants to"?  The answer changes whether I would just close the reference immediately, or save them and close them when my program is quitting.

 

I would love to get rid of the global variable, and completely agree they are unnecessary in general.  However, this one is used in parts of my code which I am not modifying for this update, therefore I cannot change it at this time.  Incidentally, there is a Preview Queue Element VI which would work perfectly for a Stop Queue - it leaves the element on the queue.  I imagine a notifier would work just as well; I would set either of them to timeout immediately and just check whether it timed out or not.

 

I was originally wiring the 4 static VI references directly to Invoke nodes, but since then I have been using your suggested layout above, to make sure I get a different VI reference for each of the instances of my re-entrant VI when I run it in a for loop.

 

Thank you very much for your assistance!  I look forward to finding out if you run into the same problem with compilation into an executable.

0 Kudos
Message 11 of 19
(1,753 Views)

Diane, In a one to many relationship certainly the notifier, occurance or dynamic event (depending on the sub vi) would be the better "queue" types.  Parhaps the naming of the functions on the "Queue Operations" palatte is a bit missleading.  I didn't mean to confuse anyone by using the generic word "queue" encompassing the several means of passing data within a app instance found under "Synchronization" (I Almost expect dynamic events on this palatte too).


"Should be" isn't "Is" -Jay
0 Kudos
Message 12 of 19
(1,752 Views)

Ha!  I'm obviously looking at an old help file, not too strange since I have an old version open on my computer just now (LV 8.5).  I do understand your concern, and it makes sense.

 

So what I'd do is close the references explicitly in the main VI.  I'd trap for an error from your Invoke node and take action based on that (i.e. close the references).  If no error occurs, then close the references at the end of your program.  Just index your array of references into another FOR loop and close them one by one.

 

I do not believe that merely closing the reference causes the subVI to cease execution.  In fact, I'm pretty sure it doesn't, (someone please correct me if I'm wrong), so you'll want to make sure the subVI has actually stopped before you close the reference.

 

Ok, more later.

 

Jeff, I get what you were saying now!  I don't use "queue" as a generic term because I am too easy to confuse.  🙂

0 Kudos
Message 13 of 19
(1,746 Views)

Ok, I had a look and was, indeed, able to duplicate your problem.  I've attached a little project I wrote.  When I made an executable out of "main", I had to designate "generate graph.vi" as "Always Included" in the build, even though the main application has a static reference to it.  If I did NOT designate "generate graph.vi" as "Always Included", the executable claimed that it couldn't load the front panel of "generate graph.vi" when I spawned a copy.  When you look at the build spec, note that "remove front panel" is NOT checked.

 

So, I decided to write another main program, one that loaded a subVI into a subpanel instead of one that spawned copies...just in case the behavior had something to do with the subVI being reentrant.  That's "main2".  It loads "generate graph non reentrant" into a subpanel.

 

I encountered the same problem when I built "main2" into an executable.  Again, "remove front panel" is NOT checked.  When running "main2" as an executable, it tells me that it can't load "generate graph non reentrant" into the subpanel because its front panel isn't accessible.

 

Now, this is weird, because I've used static VI references to load subVIs into subpanels before, and had no trouble when I made executables out of the calling VIs.  I went back and looked at some of that code, and the build specifications, and I'm not seeing where the differences are.  (That code was written for clients, and it's proprietary so I can't post it.)  I can say that the way I obtained the references to the static VIs is exactly the same in both cases.  So there's either something about the subVIs that's different, or something about the build setup.  I did check both build setups, and they appear to be the same too.

 

Obviously something's different, but it's not jumping out at me.

 

Could someone smarter than I am have a look at this and tell me what I'm forgetting or not seeing?

0 Kudos
Message 14 of 19
(1,740 Views)

 

I won't claim to be someone smarter than you but I looked at it anyhow.

 !bam.png

 

Don't remove the Front Panel and Bob's your uncle.  Nice examples and it works without allways include!


"Should be" isn't "Is" -Jay
Message 15 of 19
(1,736 Views)

Jeff, I thought we agreed some time ago that you're smarter than I am.  🙂

 

I only looked at the settings for the top-level VIs (i.e. main and main2), to ensure that front panels were included.  Not the subVIs.

 

<Diane smacks forehead>

 

I mean, it's not as though the error message didn't tell me what the problem was.

 

<smacks forehead again>

 

That makes so much sense...in my other projects, it's been VIs I developed as top-level modules that I've called via static references.  I often find I need to do a project in stages  -- I'd develop a module, deploy it as a standalone so they'd have something to use while the full application was being developed, and when I was ready to combine all of the modules under an umbrella, I'd flip the appropriate switches inside the modules and call them statically from the full application.

 

So there's the difference I was looking for.  I've been statically calling top-level VIs developed in different lvprojects, so the default save setting was to include the front panel.

 

You are super awesome!

Message 16 of 19
(1,731 Views)

@DianeS wrote:

<Diane smacks forehead>

 


<smacks forehead again>

 



Careful- those neck injuries can have delayed effects!  

 

Keep 'em comming!  (and I would require you to "spot me ten" in any IQ competitionSmiley Wink)


"Should be" isn't "Is" -Jay
0 Kudos
Message 17 of 19
(1,727 Views)

I'd know.

 

(about neck injuries, that is)

 

🙂

 

I'll spot you 10 if I can have 15 back...

 

(Sorry to the OP, Jeff and I are renewing an old and enjoyable acquaintance.  We'll get back on topic whenever you need us to.)

0 Kudos
Message 18 of 19
(1,722 Views)

Thank you, Jeff, that indeed fixed the "always include" problem for me as well.  Kudos to you and your post, but I'm going to mark Diane's original fix for my first problem (launching in a for loop) as the official Solution to this post.  I very much appreciate both of your help, though!  Smiley Happy

 

For the edification of others reading this post, I tried closing the re-entrant VI references immediately after Invoke:Running them, and it appeared to stop the instances of that VI immediately.  Since apparently I am supposed to close the references if an error occurs even if I mark the Invoke node as "Auto Dispose Ref", I have left that property as False, and stored the references in an array to close via a for loop when my program is exiting.  That solution seems to be working well.

 

Cheers,

 

-Joe

0 Kudos
Message 19 of 19
(1,709 Views)