hooovahh Posted April 20, 2020 Report Share Posted April 20, 2020 Okay so I have a normal class. In that class is a private VI that I will open a reference to and run it asynchronously using the Static VI Reference, an Open Reference by name, and a Start Asynchronous Call. All normal and all good. I realized I might want to capture the response from this VI once it finally returns in the Close so I keep the reference to this VI in the class. Now for me to be able to get the response using the Wait On Asynchronous Call I need to have the VI reference be strict, which includes things like the terminals used. Notice I have a coercion dot in the image above because the Helper Reference in the class is a normal non-strict VI reference. As soon as I change this to be a strict reference my private data type has an error "VI Refnum 'Helper Reference': Private data control of this class uses an illegal value for its default data." So for now I have a non strict VI reference, going to a variant, then variant to data with the type I want, and things seem to work. Is this just some kind of recursion issue that LabVIEW can't resolve? Is there a proper way of doing this? I also just thought of another solution, that my terminals in the VI could be variants, and then just convert to and from the class data. Is this okay? Thoughts? Thanks. Quote Link to comment
Aristos Queue Posted April 21, 2020 Report Share Posted April 21, 2020 You cannot use any reference to the class itself within the class. Technically, we could enable some things, like a DVR of the class within the same class, because the default value is Not A Refnum. But we chose -- consciously -- to make the rule "no references to yourself in your own private data." It's an easier rule to teach, and it has various performance benefits for initialization (that mattered more on the hardware from 13 years ago than they do today). And it has come up very rarely. In fact, I think you're the first person whose asked me specifically about the VI reference case. All the others have a reasonable workaround... need an array of X? Use an array of its parent class (which may be LV Object). Same trick works for most refnums... or you can always cast a refnum as an integer and cast it back when you need to talk to its data. But casting doesn't work on strict VI refs and you cannot use it as its parent class type. I think you're stuck. I can't see a way out of that box. 1 Quote Link to comment
drjdpowell Posted April 21, 2020 Report Share Posted April 21, 2020 An alternate design is to not use "Wait On Asynchronous Call" and instead pass in a Queue that you use to return the Object. That's the design I would use in any case (I've never used Wait On Asynchronous Call). Your Queue can be a queue of a parent class. 1 1 Quote Link to comment
Tim_S Posted April 21, 2020 Report Share Posted April 21, 2020 Don't know if this will work with your design, but... I have a similar situation of class reference to itself. The code is the base object for plugins and gets compiled into a packed library. The class has a vit inside of it that the child uses to create a version that it sets in a property. The property is strictly typed to the vit and gets called by the parent. To make this work I had to put a control of the reference in the library the parent class is in. This is the way I was able to get around a reference to a class within itself. 1 Quote Link to comment
hooovahh Posted April 21, 2020 Author Report Share Posted April 21, 2020 Thanks, great incite, and great suggestions. So far that means I see 4 possible solutions. 1) Use a non-strict VI reference and do the To Variant-To Strict VI reference dance I showed in the first post (this does work BTW) 2) Have the terminals be variants, then use variant to data with my class in the VI, and then in the VI with the Wait On Asynchronous Call. 3) Use a queue or some other reference to get the same data, without using the Wait On Asynchronous. 4) Tim's solution. I've gone with the Variant terminal solution 2. The calling and closing of the asynchronous VI is controlled by two private VIs in that class and should always return no error. Had I realized this wouldn't work from the start I would go with solution 3 using probably a DVR, but I already had the VIs written and just needed to add some variant to data calls. Quote Link to comment
GregFreeman Posted April 21, 2020 Report Share Posted April 21, 2020 (edited) FWIW, I have always just stored this in a variant in the class private data, and written a private wrapper VI to convert to and from the reference/variant. It makes me twitch slightly every time I do it, but it's functional so that's good enough for me. It's ironic because I just used this the other day, and was debating posting a question on this subject -- whether or not anyone else was using start async call nodes with wait on async call to run things like dialogs. I have been using this to manage the shutdown sequence of windows or processes that run dynamically, even if I don't need data back, and ensuring they finish before I close references etc. Each dynamic process keeps a reference to any child processes they launch, and when my app shuts down, each layer is responsible for waiting for all async calls to finish before they finish. It seems to nicely propagate up the stack. Just here waiting for someone to tell me about some caveat I didn't consider Edited April 21, 2020 by GregFreeman 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.