views:

149

answers:

5

In LabVIEW, is it possible to tell from within a VI whether an output terminal is wired in the calling VI? Obviously, this would depend on the calling VI, but perhaps there is some way to find the answer for the current invocation of a VI.

In C terms, this would be like defining a function that takes arguments which are pointers to where to store output parameters, but will accept NULL if the caller is not interested in that parameter.

+1  A: 

Generally, no.

It is possible to do a static analysis on the code using the "scripting" features. This would require pulling the calling hierarchy, and tracking the wire references.

Pulling together a trial of this, there are some difficulties. Multiple identical sub-vi's on the same diagram are difficult to distinguish. Also, terminal references appear to be accessible mostly by name, which can lead to some collisions with identically named terminals of other vi's.

NI has done a bit of work on a variation of this problem; check out this.

Underflow
+1  A: 

Like Underflow said, the basic answer is no.

You can have a look here to get the what is probably the most official and detailed answer which will ever be provided by NI.

Extending your analogy, you can do this in LV, except LV doesn't have the concept of null that C does. You can see an example of this here.

Note that the code in the link Underflow provided will not work in an executable, because the diagrams are stripped by default when building an EXE and because the RTE does not support some of properties and methods used there.


Sorry, I see I misunderstood the question. I thought you were asking about an input, so the idea I suggested does not apply. The restrictions I pointed do apply, though.

Why do you want to do this? There might be another solution.

Yair
I don't have a specific application in mind -- but consider a C function with the signature `void get_size(int *height, int *width)` where either `height` or `width` may be `NULL` if you only need one dimension, but where they share enough code that it doesn't make sense to calculate both separately if you need both.
ptomato
+3  A: 

As it was said you can't do this in the natural way, but there's a workaround using data value references (requires LV 2009). It is the same idea of giving a NULL pointer to an output argument. The result is given in input as a data value reference (which is the pointer), and checked for Not a Reference by the SubVI. If it is null, do nothing.

Here is the SubVI (case true does nothing of course):

alt text

And here is the calling VI:

alt text

Images are VI snippets so you can drag and drop on a diagram to get the code.

CharlesB
It's worth noting that this *is* similar to passing a pointer, but doesn't actually tell you anything about the output. (It's rather clever, as well!)
Underflow
A: 

In general, the LV compiler optimizes the machine code in such a way that unused code is not even built into the executable.

This does not apply to subVIs (because there's no way of knowing that you won't try to use the value of the indicators somehow, although LV could do it if it removes the FP when building an executable, and possibly does), but there is one way you can get it to apply to a subVI - inline the subVI, which should allow the compiler to see the outputs aren't used. You can also set its priority to subroutine, which will possibly also do this, but I wouldn't recommend that.

Officially, in-lining is only available in LV 2010, but there are ways of accessing the private VI property in older versions. I wouldn't recommend it, though, and it's likely that 2010 has some optimizations in this area that older versions did not.

P.S. In general, the details of the compiling process are not exposed and vary between LV versions as NI tweaks the compiler. The whole process is supposed to have been given a major upgrade in LV 2010 and there should be a webcast on NI's site with some of the details.

Yair
+1  A: 

I'd suggest you're going about this the wrong way. If the compiler is not smart enough to avoid the calculation on its own, make two versions of this VI. One that does the expensive calculation, one that does not. Then make a polymorphic VI that will allow you to switch between them. You already know at design time which version you want (because you're either wiring the output terminal or not), so just use the correct version of the polymorphic VI.

Alternatively, pass in a variable that switches on or off a Case statement for the expensive section of your calculation.

eaolson