mje Posted October 17, 2008 Report Share Posted October 17, 2008 I'm trying to reinvent a framework using GOOP, and I've hit a brick wall. I have a member VI that needs to be dynamically dispatched. The caveat is I'd like to call said method asynchronously (not waiting for it to return). Now I see a few problems with this given my knowledge of how dynamic dispatches and VI server work, but the first one is the most general. How do you invoke a dynamically dispatched VI asynchronously? I've tried my usual way (read: only way of which I'm aware) of opening a VI reference, setting a control value, and invoking it: I expected an error here, and sure enough, LabVIEW doesn't disappoint: Error 1000 occurred at Invoke Node in Test.vi Possible reason(s): LabVIEW: The VI is not in a state compatible with this operation. Method Name: Run VI VI Path: C:\Users\michael\Desktop\Asychronous Dynamic Dispatch\Base\Foo.vi Now I expected an error to arise from the polymorphic nature of object wires...the whole idea of the dispatch is to determine which VI of a given interface to invoke at runtime, and I'm handing LV a reference to a specific implementation and asking it to do its thing. Don't know if that's related to the error at hand, but in the end it didn't surprise me. And this is as far as I've gotten...I keep coming back to the same problem of being unable to define which method is going to be called at design time, yet VI Server requiring a specific reference. Anyone know a way to deal with this? Regards, -Michael Quote Link to comment
Jeffrey Habets Posted October 17, 2008 Report Share Posted October 17, 2008 I'm a bit short on time now and haven't really given any thought on your description and if it should work or not that way. But here's what I do in my code and this works like a charm.. Thread.vi is in my case a private method and thus not dynamic dispatch, but it in turn calls dynamic dispatch methods on the DAQ class which are overriden in the child classes. I think this should do the trick in your case also. Quote Link to comment
shoneill Posted October 17, 2008 Report Share Posted October 17, 2008 QUOTE (MJE @ Oct 16 2008, 05:29 AM) I'm trying to reinvent a framework using GOOP, and I've hit a brick wall. I have a member VI that needs to be dynamically dispatched. The caveat is I'd like to call said method asynchronously (not waiting for it to return).Now I see a few problems with this given my knowledge of how dynamic dispatches and VI server work, but the first one is the most general. How do you invoke a dynamically dispatched VI asynchronously? I've tried my usual way (read: only way of which I'm aware) of opening a VI reference, setting a control value, and invoking it: http://lavag.org/old_files/monthly_10_2008/post-11742-1224126314.png' target="_blank"> I expected an error here, and sure enough, LabVIEW doesn't disappoint: Error 1000 occurred at Invoke Node in Test.vi Possible reason(s): LabVIEW: The VI is not in a state compatible with this operation. Method Name: Run VI VI Path: C:\Users\michael\Desktop\Asychronous Dynamic Dispatch\Base\Foo.vi Now I expected an error to arise from the polymorphic nature of object wires...the whole idea of the dispatch is to determine which VI of a given interface to invoke at runtime, and I'm handing LV a reference to a specific implementation and asking it to do its thing. Don't know if that's related to the error at hand, but in the end it didn't surprise me. And this is as far as I've gotten...I keep coming back to the same problem of being unable to define which method is going to be called at design time, yet VI Server requiring a specific reference. Anyone know a way to deal with this? Regards, -Michael You can launch the VI and then send the actual object via user event, queue or notifier. The launched VI waits for this information (You can pass the event refnum or further via VI server before running it) and then launches the base class of the Dynamic dispatch VI which will retain the "dynamic dispatch" part. This way you don't have to go via Variant. So what I'm saying is that the code for launching the VI without waiting belongs IN the class. That way you should be able to do what you are looking for without sacrificing the automatic dynamic dispatch handling. Shane. Quote Link to comment
Francois Normandin Posted October 17, 2008 Report Share Posted October 17, 2008 Hi Michael, I could not reproduce the error you get (I'm using LV 8.6). I'm not sure if the version makes the difference, but anyway, the dynamic dispatch didn't work. I created A & B (B inherited from A) and the VI dynamically called was always A, whatever I did. As you said, I kind of expected it... but I didn't get the errors you mentioned. After all, B object can propagate on A-type wire. I always got the result expected if A:Calculate was called. So yes, it works with static dispatch... but not dynamical. I'm sure AQ will step in to give the exact reason why it doesn't (or maybe shouldn't ever) work. QUOTE (shoneill @ Oct 16 2008, 05:35 AM) You can launch the VI and then send the actual object via user event, queue or notifier. The launched VI waits for this information (You can pass the event refnum or further via VI server before running it) and then launches the base class of the Dynamic dispatch VI which will retain the "dynamic dispatch" part.This way you don't have to go via Variant. So what I'm saying is that the code for launching the VI without waiting belongs IN the class. That way you should be able to do what you are looking for without sacrificing the automatic dynamic dispatch handling. Shane. Hi Shane, I don't understand how you will know which instance to call even by wrapping the object in a queue/notifier/user event. If we don't know yet which VI will be called (parent or child), how do you unwrap from the queue when the code is dynamically called? The way I imagine it (not tried this yet), I don't know how I can avoid ending up with the parent object type. Quote Link to comment
Aristos Queue Posted October 17, 2008 Report Share Posted October 17, 2008 Create a non-dynamic subVI that has a call to the dynamic dispatch method on its block diagram. Then use VI Server to call that subVI. Quote Link to comment
Francois Normandin Posted October 17, 2008 Report Share Posted October 17, 2008 QUOTE (normandinf @ Oct 16 2008, 09:47 AM) I'm sure AQ will step in to give the exact reason why it doesn't (or maybe shouldn't ever) work. it works and I'm too pessimistic about this Quote Link to comment
shoneill Posted October 17, 2008 Report Share Posted October 17, 2008 QUOTE (normandinf @ Oct 16 2008, 03:47 PM) Hi Shane, I don't understand how you will know which instance to call even by wrapping the object in a queue/notifier/user event. If we don't know yet which VI will be called (parent or child), how do you unwrap from the queue when the code is dynamically called? The way I imagine it (not tried this yet), I don't know how I can avoid ending up with the parent object type. Well I was under the impression that you don't NEED to know the internal class representation. Even casting all objects in an array to a base class will still call the CORRECT dynamic dispatch VI when using those objects. So just casting an object as a parent class does not make it suddenly call the parent version of a dynamic dispatch VI. It will still call the correct dynamic dispatch VI. The QUEUE/notifier/Event simply avoids variant which could otherwise be problematic. As AQ has already stated, a single VI with a dynamic dispatch call will do the trick. My idea was to have this VI AQ is referring to within the class, in essence moving the "dynamic dispatch" part up one level. Getting the exact VI refnum might be problematic though, so AQ's solution gets around that. Shane. Shane. Quote Link to comment
Francois Normandin Posted October 17, 2008 Report Share Posted October 17, 2008 QUOTE (shoneill @ Oct 16 2008, 10:46 AM) Well I was under the impression that you don't NEED to know the internal class representation. Even casting all objects in an array to a base class will still call the CORRECT dynamic dispatch VI when using those objects. So just casting an object as a parent class does not make it suddenly call the parent version of a dynamic dispatch VI. It will still call the correct dynamic dispatch VI. The QUEUE/notifier/Event simply avoids variant which could otherwise be problematic.As AQ has already stated, a single VI with a dynamic dispatch call will do the trick. My idea was to have this VI AQ is referring to within the class, in essence moving the "dynamic dispatch" part up one level. Getting the exact VI refnum might be problematic though, so AQ's solution gets around that. Shane. Shane. Now I see. I didn't get what you were explaining at first. Sorry for the confusion. Quote Link to comment
shoneill Posted October 17, 2008 Report Share Posted October 17, 2008 QUOTE (normandinf @ Oct 16 2008, 05:20 PM) Now I see. I didn't get what you were explaining at first. Sorry for the confusion. Well since I was (supposedly) the one doing the explaining, shouldn't the apology be from me? Just do whatever AQ says (or writes). Where's the "Set current value to default" for these Forums :worship: Shane. Ps Forgot the actual apology.... Sorry (for forgetting). Sorry (For confusion). Quote Link to comment
mje Posted October 18, 2008 Author Report Share Posted October 18, 2008 Wrapping the method should work, thanks for the advice all. 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.