Jump to content

Static VI References with Class, in Class not allowed?


Recommended Posts

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.

1555973807_StartHelper.png.6b24e84e0cec43fc586f27855646dc8d.png

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.

Close.png.48dcc54e5009e59ad3b9e93c25a39cde.png

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.

Link to comment

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. 

  • Like 1
Link to comment

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.

  • Like 1
  • Thanks 1
Link to comment

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.

image.png.4a11edbbfdecf837e803671b4ab73ddb.png

image.png.f279a97d4b01dc95827c2d4f20a6a486.png

  • Like 1
Link to comment

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.

Link to comment

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 by GregFreeman
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.