LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

.NET assemblies, local variables and state machines

Solved!
Go to solution

Hi!

 

Summary of issue: I have attempted to use local variables and shift registers to pass .NET assembly references (or are they object instance references?) between two states of a state machine. This does not work, and I need your kind help understanding why. I am going to give as much detail as I can, because I don't necessarily know what everything's name is.

 

I am writing a state machine (I directly modified the LabVIEW example) in LV 2010 SP1. This state machine is simple and communicates with one instrument over USB. There are two .NET assemblies required for communication with this instrument. I have them sitting at the same level as the .vi file and its project. Here they are as seen in Windows Explorer. Ain't they cute?

 

Capture.PNG

 

I have a "Find Device" case, a "Perform Test" case and a "Finished Testing" case (as well as all the others, like the initialization case, the idle case and other things not relevant to this post). In "Find Device", I call the initialization VI that the instrument manufacturer provided and then proceed to set up the device. Here is that Initialize.vi:

 

Capture1.JPG

 

Inside the VI is a series of method calls that set everything up and ultimately return an array of strings with the Device Keys of the discovered instruments. I want to call your attention to the two teal-coloured lines coming out of these constructors, which is how everything starts. These are references to a DeviceIOLib object and a CmdLib6800 object. Is that correct? I am going to go with that nomenclature for now.

 

Capture2.JPG

 

Back to my "Find Device" case. If I wire every device VI with their required CmdLib6800 reference and the right DeviceKey string, every single instrument VI in this "Find Device" case is happy and the device functions well. 

 

Trouble starts when I want to move over to the "Perform Test" case. I thought I'd be smart and use local variables (yes, I am in control of potential race conditions. My state machine is very simple!), like so:

 

Capture3.JPG

 

And then, once the "Find Device" case is finished and I pop into the "Perform Test" case, and read the object reference and DeviceKey (please ignore breakpoint/probe):

 

Capture4.JPG

 

That's where the fun starts. The very first VI that gets passed this reference from the local variable (the one seen above) fails with an error. Inside that VI is the following:

 

Capture5.JPG

 

I have placed a probe on the error line of the invoke node, and here's what it says: 

 

Capture6.JPG

 

For the benefit of those searching the forum later, here is the text:

 

 

Error 1172 occurred at Error calling method [REDACTED].CmdLib6800.GetOutputEnable, (System.ArgumentNullException: Key cannot be null.
Parameter name: key)
Possible reason(s):
LabVIEW: A .NET exception occurred in an external assembly. For information about correcting this error, copy the following exception (in bold), and search the Microsoft Developer Network (MSDN) Web site or the Web for a possible explanation.
System.ArgumentNullException in GetOutputEnable_6800.vi

 I am assuming that this means that my local variable trick didn't work. As a quick workaround (because this program is due in five days, what else is new... 😕 ) I tried wiring these teal-coloured lines from the "Find Device" to the state machine's outside while loop, and added a shift register. I then tried reading them back into the "Perform Test" case, but that did not work either. 

 

Could you fine folks please help me understand:

 

  • What is a simple, functional way of ensuring that the second case ("Perform Test") gets the right reference so that the invoke nodes work? Please note that I do not have time to move the program to another paradigm (event queue, etc) nor to learn and gain confidence with possibly more advanced and elegant tricks. My state machine is simple, the use case is simple, and so I am hoping for a simple solution.

 

  • What should I do to wrap things up in the "Finished Testing" case after I have finished with the "Perform Test" case? Here's what I had done, but I would imagine this doesn't work either: 

Capture7.JPG

Inside each of these VIs there is just an invoke node calling a shutdown method, but no explicit LabVIEW VIs from the .NET panel to close out the references—though I have no idea if that is necessary.

 

 

Anyway, that is my issue and I hope I have made it clear and easy to read. I would really appreciate your help and guidance. 

 

Thanks!

0 Kudos
Message 1 of 6
(3,683 Views)

@paulwb wrote:

 

 I am assuming that this means that my local variable trick didn't work. As a quick workaround (because this program is due in five days, what else is new... 😕 ) I tried wiring these teal-coloured lines from the "Find Device" to the state machine's outside while loop, and added a shift register. I then tried reading them back into the "Perform Test" case, but that did not work either. 


I would suspect that your bug is something like calling your cases in the wrong order, or calling some other case that overwrites the variable with a null reference.  There is no reason why shift registers or local variables wouldn't work in passing a reference.

0 Kudos
Message 2 of 6
(3,605 Views)

@drjdpowell wrote:

@paulwb wrote:

 

 I am assuming that this means that my local variable trick didn't work. As a quick workaround (because this program is due in five days, what else is new... 😕 ) I tried wiring these teal-coloured lines from the "Find Device" to the state machine's outside while loop, and added a shift register. I then tried reading them back into the "Perform Test" case, but that did not work either. 


I would suspect that your bug is something like calling your cases in the wrong order, or calling some other case that overwrites the variable with a null reference.  There is no reason why shift registers or local variables wouldn't work in passing a reference.


Thank you for your reply. When I get back to work on Tuesday I will check to see if this is the case, but I thought I had checked for this already. Mainly what I was hoping for information on is whether my technique is valid, and you say it is, so I'm still puzzled. 

 

On a related note, how would I blank out these references on purpose? Perhaps there is a null reference element I can place on the block diagram (I don't have LV at home to check, sorry).

 

 

0 Kudos
Message 3 of 6
(3,592 Views)

@paulwb wrote:

@drjdpowell wrote:

@paulwb wrote:

 

 I am assuming that this means that my local variable trick didn't work. As a quick workaround (because this program is due in five days, what else is new... 😕 ) I tried wiring these teal-coloured lines from the "Find Device" to the state machine's outside while loop, and added a shift register. I then tried reading them back into the "Perform Test" case, but that did not work either. 


I would suspect that your bug is something like calling your cases in the wrong order, or calling some other case that overwrites the variable with a null reference.  There is no reason why shift registers or local variables wouldn't work in passing a reference.


Thank you for your reply. When I get back to work on Tuesday I will check to see if this is the case, but I thought I had checked for this already. Mainly what I was hoping for information on is whether my technique is valid, and you say it is, so I'm still puzzled. 

 

On a related note, how would I blank out these references on purpose? Perhaps there is a null reference element I can place on the block diagram (I don't have LV at home to check, sorry).

 

 


A few comments from me:

  • The error 1172 you are getting is just LabVIEW's way of wrapping around every .Net Exception that gets thrown - but if the object is a null reference you do get a different error (LV knows the difference). The source component of the error cluster is a little annoying I agree - it only takes out some of the Exception components and doesn't expose others (such as the stack-trace for example) that could allow you to dig into what is throwing the exception in this case. There is an idea exchange somewhere around this topic - feel free to up-vote it.
  • There is nothing wrong with using .Net object references as you describe (from a strategy perspective). I do it all the time, although I recommend not using local variables, of course.
  • Based on your error I'm in agreement with other comments made here - the error is likely a logical one rather then anything specificalyl .Net.
  • LabVIEW pins .Net objects in memory while they are in use and un-pins them (to allow the GC to operate) when they are no longer referenced - ie. the wire ends or you wire a null reference. It's fairly easy to do - just right-click on the shift register going out of your state machine and create a new constant.

 

Message 4 of 6
(3,583 Views)

In my experience 1172 is _some_ .net error, often some help/config-object needs to be created. If that applies in your case i dont know, but worth a check.

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 5 of 6
(3,559 Views)
Solution
Accepted by topic author paulwb

Thank you, tyk007 and Yamaeda. The error indeed turned out not to be related to my use of local variables with object references. It was due to the fact that I was using a Device_Write method for a couple of hand-crafted instructions (instead of the pre-packaged instruction VIs) when I should have been using Device_Query. As a result, the instrument and the controlling library were getting out of sync (I wasn't clearing the output buffer with a read following my write), and the method call for subsequent query commands would throw an error when the library didn't get the type of response it was expecting ('OK' instead of a number, for example). I figured this out with help from the original instrument VI developer, suggesting I check the log file that this library can optionally create. 

 

Thank you everyone for your help!

Message 6 of 6
(3,460 Views)