mje Posted October 22, 2010 Report Share Posted October 22, 2010 Is there any sort of LabVIEW voodoo that allows you to propagate type information for a refnum through a VI? I have VIs which take generic Control Refnums in then out, but the problem is the output always looses it's type info. So I can't ever use the output to wire up to another VI which operates on a more specific class, even if I supplied that class to the input. Example, this little bit of code I've been using for ages which defers panel updates which I'm sure many of us can relate to in one form or another: I have VIs that operate on refnums of one type or another (especially XML) that I'd really like to not have to always "branch off" the refnums to be able to operate on them. Is there a way to do this, sort of similar to how type info is propagated for LabVIEW objects? I'll add I'm aware I can just make a ton of polymorphic VIs. I've even done as much. But it's kind of kludgy, and requires an implementation for every kind of refnum... Quote Link to comment
ShaunR Posted October 22, 2010 Report Share Posted October 22, 2010 (edited) I'm not sure what your asking here. Type information? If you mean the controls class (e.g boolean, string etc) then it is propagated (if you inspect the class name you will see it). If you mean you cannot connect a parent class refnum to a child class refnum and have it automagically choose the appropriate refnum then no. Because "classic" Labview doesn't support run-time polymorphism. You have to go to OOP and use dynamic despatch (which wouldn't be much different from creating your polymorphic VI). The only way I know of that you could achieve a similar behaviour in classic LV is to make all your refnums variants and coerce to the specific class within each VI. But then you can connect anything to anything so it wouldn't flag up (for example) that you had connected a real control rather than a refnum until you ran it. Edited October 22, 2010 by ShaunR Quote Link to comment
Matt W Posted October 22, 2010 Report Share Posted October 22, 2010 Is there any sort of LabVIEW voodoo that allows you to propagate type information for a refnum through a VI? I have VIs which take generic Control Refnums in then out, but the problem is the output always looses it's type info. So I can't ever use the output to wire up to another VI which operates on a more specific class, even if I supplied that class to the input. Example, this little bit of code I've been using for ages which defers panel updates which I'm sure many of us can relate to in one form or another: I have VIs that operate on refnums of one type or another (especially XML) that I'd really like to not have to always "branch off" the refnums to be able to operate on them. Is there a way to do this, sort of similar to how type info is propagated for LabVIEW objects? I'll add I'm aware I can just make a ton of polymorphic VIs. I've even done as much. But it's kind of kludgy, and requires an implementation for every kind of refnum... Your code has a memory leak. The reference created by OwningVI needs to be closed. I have a similar bit of code and it took me half a day to track down that memory leak. You can use the desktop execution trace to find hanging references (which didn't exist back then). Quote Link to comment
mje Posted October 22, 2010 Author Report Share Posted October 22, 2010 Are you sure about that memory leak? I thought one should only close refnums which you explicitly open? Haven't played with the desktop execution toolkit yet... Also, with regards to Shaun's questions, first please see the screenshot. Code used to generate it is also attached. If you mean you cannot connect a parent class refnum to a child class refnum and have it automagically choose the appropriate refnum then no. Because "classic" Labview doesn't support run-time polymorphism. You have to go to OOP and use dynamic despatch (which wouldn't be much different from creating your polymorphic VI). I'm actually looking for the opposite of run-time polymorphism. I'd like a way for static compile time info to somehow be propagated. Take for example how you can wire up a parent method of an OOP class in the middle of a child class wire, without the wire being coerced to a parent class (shown in the bottom of the screenshot). LabVIEW is smart enough with objects to be able to figure out when type information can be propagated through a VI call with objects at compile time, it would be wonderful if that could also apply to refnums... Is that more clear? I'll point out that this is more of an "I wish it existed" post than "Is there a way to do it?" post... RefnumDemo.zip Quote Link to comment
Stagg54 Posted October 22, 2010 Report Share Posted October 22, 2010 I'll point out that this is more of an "I wish it existed" post than "Is there a way to do it?" post... That sounds like an idea for the Idea Exchange. Quote Link to comment
Matt W Posted October 22, 2010 Report Share Posted October 22, 2010 Are you sure about that memory leak? I thought one should only close refnums which you explicitly open? I'm certain. The explicitly open is generally true in my experience, but Owning VI is an example of when it's not true. The desktop trace confirms it, if you cast the ref to an integer, its value changes for each call, and if you run it in a tight loop memory use will grow without bound (no super fast though, it's only leaking a pointer sized int). The desktop trace toolkit could be better (like tracking which event in the event structure was triggered). The tracing is good for debugging heavily multithreaded code. The ability to find unclosed references and check how LabVIEW is really allocating memory make it uniquely useful. Quote Link to comment
jzoller Posted October 22, 2010 Report Share Posted October 22, 2010 Can you use just generic control references for controls/indicators, and calls to To More Specific Class inside of each vi with a specific type? If To More Specific Class errors, the cast is invalid, and you can behave appropriately. Just a (possibly fever induced) thought... a quick and dirty sample seemed to work for me. Joe Z. Quote Link to comment
asbo Posted October 22, 2010 Report Share Posted October 22, 2010 Can you use just generic control references for controls/indicators, and calls to To More Specific Class inside of each vi with a specific type? If To More Specific Class errors, the cast is invalid, and you can behave appropriately. Just a (possibly fever induced) thought... a quick and dirty sample seemed to work for me. Joe Z. Yeah, I've seen something of that nature before with a while loop and a case statement - cover all the cases you think you'll need. It is definitely a kludgey solution, but a solution nonetheless. Quote Link to comment
Jarrod S Posted October 23, 2010 Report Share Posted October 23, 2010 Is there any sort of LabVIEW voodoo that allows you to propagate type information for a refnum through a VI? This is sort of a non-answer, but it helps me and I think has merit. What I always do in this situation is not pass the refnum back out from the subVI. There is only a refnum input. This prevents the caller from accidentally doing the cast to a more generic class. It has the downside that the calling code is a little uglier, since it can't railroad the refnum wire through for multiple calls to such subVIs. Quote Link to comment
ShaunR Posted October 23, 2010 Report Share Posted October 23, 2010 (edited) I'm actually looking for the opposite of run-time polymorphism. I'd like a way for static compile time info to somehow be propagated. Take for example how you can wire up a parent method of an OOP class in the middle of a child class wire, without the wire being coerced to a parent class (shown in the bottom of the screenshot). LabVIEW is smart enough with objects to be able to figure out when type information can be propagated through a VI call with objects at compile time, it would be wonderful if that could also apply to refnums...Is that more clear? I'll point out that this is more of an "I wish it existed" post than "Is there a way to do it?" post... I see what you mean. But your "Class" example isn't exactly analogous to the VI example (just being picky ). If you inspect your middle VI, you will see there is a coercion dot. So the equivalent class implementation would be As you can see. this also has the same issue. The class example is really analogous to creating a polymorphic VI Edited October 23, 2010 by ShaunR Quote Link to comment
Jarrod S Posted October 23, 2010 Report Share Posted October 23, 2010 I see what you mean. But your "Class" example isn't exactly analogous to the VI example (just being picky ). If you inspect your middle VI, you will see there is a coercion dot. So the equivalent class implementation would be As you can see. this also has the same issue. The class example is really analogous to creating a polymorphic VI I think what is wanted is that there is not a coercion dot, because the coercion never happens. The type should be propagated across the subVI without changing. Quote Link to comment
ShaunR Posted October 23, 2010 Report Share Posted October 23, 2010 I think what is wanted is that there is not a coercion dot, because the coercion never happens. The type should be propagated across the subVI without changing. Agreed. It would be nice. But it kind-a indicates that coercion does happen. The VI's cannot statically change the control refnum without using polymorphism so it has no choice but to either give a broken wire or coerce the data on the wire to a compatible type. It gets even worse if you pop-up the right click menu on the boolean control ref and select "Include Data Type". You won't even be able to connect it to a standard boolean control ref. You will have to convert it to Bool(Strict) first. Quote Link to comment
Yair Posted October 23, 2010 Report Share Posted October 23, 2010 First, to answer the original question, this can be done using XNodes, but that's not officially supported and I never really played around with them. There should be an example somewhere on LAVA. This can also be done with express VIs, as shown in this thread, but I never played around with that either: http://lavag.org/topic/4007-anything-to-whatever-lv-71 Second, please go to the idea exchange and vote for this idea - Provide a better way to implement a polymorphic VI You should read this to see why this is not likely to happen soon, though: http://forums.ni.com/t5/LabVIEW-Developers-Feature/Now-available-for-download-quot-Randomize-1D-Array-vi-quot-that/m-p/1159329#U1159329 Third, Agreed. It would be nice. But it kind-a indicates that coercion does happen. What Jarrod was saying is that your example is flawed because you upcast the object yourself. If you just wire the child class directly into the parent VI it would propagate through just fine (assuming there's no overriding VI in the child class). This, of course, can only be done today using LVOOP. Quote Link to comment
ShaunR Posted October 24, 2010 Report Share Posted October 24, 2010 (edited) What Jarrod was saying is that your example is flawed because you upcast the object yourself. If you just wire the child class directly into the parent VI it would propagate through just fine (assuming there's no overriding VI in the child class). This, of course, can only be done today using LVOOP. Well. I read "I think what is wanted is that there is not a coercion dot, because the coercion never happens." to mean that even though there was a coercion dot, it wasn't being coerced. The comparison example was just to show that even in OOP, if you coerce (yes you have to do it manually) then the result is the same. Edited October 24, 2010 by ShaunR Quote Link to comment
Francois Normandin Posted October 24, 2010 Report Share Posted October 24, 2010 Well. I read "I think what is wanted is that there is not a coercion dot, because the coercion never happens." to mean that even though there was a coercion dot, it wasn't being coerced. The comparison example was just to show that even in OOP, if you coerce (yes you have to do it manually) then the result is the same. The result is not the same with OOP. Check this example where the wires for parent and child classes are different. The same thing is not true with VI server references. A boolean reference that runs through a control reference will still contain the boolean reference number, but the wire will be a control reference. You need to recast to boolean to be able to call methods that act on booleans. Quote Link to comment
mje Posted October 24, 2010 Author Report Share Posted October 24, 2010 The result is not the same with OOP. Check this example where the wires for parent and child classes are different. The same thing is not true with VI server references. A boolean reference that runs through a control reference will still contain the boolean reference number, but the wire will be a control reference. You need to recast to boolean to be able to call methods that act on booleans. Exactly, François, I think you did a better job explaining what I was trying to say. Quote Link to comment
ShaunR Posted October 24, 2010 Report Share Posted October 24, 2010 (edited) The same thing is not true with VI server references. A boolean reference that runs through a control reference will still contain the boolean reference number, but the wire will be a control reference. You need to recast to boolean to be able to call methods that act on booleans. Yes. Because it is coerced! Edited October 24, 2010 by ShaunR Quote Link to comment
mje Posted October 24, 2010 Author Report Share Posted October 24, 2010 Yes. Because it is coerced! Right! But it would be good if the compiler were smart enough to know not to coerce it, just as it does for classes. Quote Link to comment
ShaunR Posted October 24, 2010 Report Share Posted October 24, 2010 Right! But it would be good if the compiler were smart enough to know not to coerce it, just as it does for classes. Indeed. That's why I said it would be nice earlier. Although. If you think about it. When you open up the VI with the control ref. What should it display? The VI itself doesn't know what it's connected to; only the owning VI. The way "Classic" labvVew gets round this is the owning VI selects a VI with a compatible terminal and the only way you can tell it what VIs to select from is by defining a polymorphic VI. The fall-back is to coerce it, then a broken wire. Furthermore. If you think about classes (static ones). The owning VI is selecting the child class which you have previously defined. So in this instance there is no difference between a polymorphic VI and a Class (well. There maybe some but I can't think of any). After all. If you defined the "Boolean" class such that it wasn't a child (equivalent to a VI not attached to a polymorphic instance). You wouldn't be able to connect it either and Labview wouldn't even try to coerce it.. Quote Link to comment
mje Posted October 24, 2010 Author Report Share Posted October 24, 2010 I see where you're coming from. Agreed. When I open up the VI with the generic control ref, I'd expect it to only know about the generic control ref. That's the interface the VI has set by virtue of its connector pane. What would be ideal though is if the VI had some way of recording continuity between the input and output. This facility does exist in LabVIEW, for example with dynamic dispatch method for classes it is indeed required. I have no idea how this gets sorted out for static methods given that the same requirement is not in place (maybe internally the compiler is still aware of in/out continuity?). It would be nice if refnum in/outs had the same functionality, or you could have another type of in/out connector that mimics the behavior of classes for refnums, such that explicit coercion does not happen when passing child refnums to parent methods. I suspect though that the details lay in how refnums are actually implemented. Something tells me we are not dealing with a strict inheritance implementation which will always force a coercion: there is no actual polymorphism happening with refnums (or dynamic dispatching in LabVIEW language). It's probably the same fundamental difference which results in the limitations imposed on class DVRs which prevent dynamic dispatching. Now that I've thought this through, I suppose it makes sense why it is the way it is. I still don't like it though... Quote Link to comment
ShaunR Posted October 24, 2010 Report Share Posted October 24, 2010 (edited) I see where you're coming from. Agreed. When I open up the VI with the generic control ref, I'd expect it to only know about the generic control ref. That's the interface the VI has set by virtue of its connector pane. What would be ideal though is if the VI had some way of recording continuity between the input and output. This facility does exist in LabVIEW, for example with dynamic dispatch method for classes it is indeed required. I have no idea how this gets sorted out for static methods given that the same requirement is not in place (maybe internally the compiler is still aware of in/out continuity?). It would be nice if refnum in/outs had the same functionality, or you could have another type of in/out connector that mimics the behavior of classes for refnums, such that explicit coercion does not happen when passing child refnums to parent methods. I suspect though that the details lay in how refnums are actually implemented. Something tells me we are not dealing with a strict inheritance implementation which will always force a coercion: there is no actual polymorphism happening with refnums (or dynamic dispatching in LabVIEW language). It's probably the same fundamental difference which results in the limitations imposed on class DVRs which prevent dynamic dispatching. Now that I've thought this through, I suppose it makes sense why it is the way it is. I still don't like it though... Indeed. Whats missing is that a generic refnum should have the option to "adapt-to-type" instead of being coerced. Properties and methods can already do this, so if the control refnum could also adapt, all the properties and methods inside your VI would follow suit. In effect, you would have a polymorphic VI without having to declare all the sub-vis (for these types of VIs at least). Edited October 24, 2010 by ShaunR Quote Link to comment
Francois Normandin Posted October 24, 2010 Report Share Posted October 24, 2010 Indeed. Whats missing is that a generic refnum should have the option to "adapt-to-type" instead of being coerced. You've got it, we need the VI server types to be thralled like LVOOP. Quote Link to comment
mje Posted October 24, 2010 Author Report Share Posted October 24, 2010 Yes, that's exactly what I'm looking for. Quote Link to comment
ShaunR Posted October 24, 2010 Report Share Posted October 24, 2010 (edited) You've got it, we need the VI server types to be thralled like LVOOP. In fact. "classic" labview isn't that far removed from "lvoop". If you consider that controls are "setters", indicators are "getters" and inheritance is "create sub vi" Edited October 24, 2010 by ShaunR 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.