‎09-17-2013 09:07 AM
Hi All,
I am creating an abstract system which allows different communication Vi's to be run by providing the file path (all of the inputted VI's will have the same inputs and outputs). To achieve this I am using the "Open VI Reference" block and then using a series of invoke nodes to set the inputs, then I run the vi (handles communications with external devices) and then I using an invoke node to get the output and "error out" control value. The output specified is a Variant with a .net object within it.
The .net object comes from the communication vi's .net classes that are ran (but not closed). I use the ".NET object To" block to get that variant of the object. Within the main VI that runs the communication VI I use the "To .NET object" block to turn the variant (from the invoke Ctrl Val.get block) to a .net object which I then cast back to the required class using a "To More Specific Class" with the correct target class constant (taken from the communication vi).
When I put a probe on the output of the ".NET object to" output wire it shows that the .net object has the value of "Null Reference". Which then causes an error at the "To More Specific Class" block which in turn means the rest of the VI won't run.
However, if I use a sub vi instead of getting the VI reference and then using invoke nodes it works like a charm. Does anyone have any advice or guidance on how to rectify this? Apologies for the very generic explanation, the work is confidential and regretablly I can't post any images which makes it very hard to explain what on earth I am doing.
Thanks,
Alex
Solved! Go to Solution.
‎09-23-2013 04:05 AM
Hi Alex,
Could you give me more information about the error you are receiving? An error code would be handy. Also could I ask you to tell me what version of LabVIEW you are using?
Kind regards,
‎09-23-2013 12:29 PM
If I understand correctly: you're trying to pass a .NET object from a dynamically-called VI back to the main VI that launched it, using CtrlVal.Get? And you are calling CtrlVal.Get after the dynamically-called VI has finished running?
My guess is that the .NET object is allocated as a reference. Running a VI dynamically using Run causes that VI to be launched as a top-level VI. When a top-level VI goes idle (stops running), all of its references are cleaned up, so the .NET object gets deallocated. LabVIEW has no way to know that you've passed a reference to that object to some other VI that still wants to use it. Unfortunately I can't suggest a simple way to handle it. I think you could store the .NET object in a functional global variable that is shared between both the dynamically-called VI and the main VI, and then the functional global would hold on to it because it is still active in the main VI's context - but you'd have to test that. Another option is to create the .NET object in the main VI and pass it to the dynamically-called VI, so that its lifetime is dependent on the main VI.
‎09-24-2013 06:05 AM
MHutch - The error code was 1172 and I am using version 12.0f3
nathand - That is correct yes. I assumed the same thing, after many hours of trying to get it to work I caved and changed the system to one single vi by joining the two vi's together. I have been told that using global variables isn't great practise on RT devices therefore I wanted to try and avoid that.
Thanks for the help,
Alex
‎09-24-2013 06:13 AM - edited ‎09-24-2013 06:13 AM
A global wouldn't help with this. Refnums are not recounted in LabVIEW but their lifetime is determined by the lifetime of the top level VI in whose hierarchy it was created. And the Run VI method indeed executes the VI as independent top level instance. The proper way to deal with that is either to create the refnum in the main hierarchy or any hierarchy that stays executing for the duration of the desired refnum lifetime or to execute the VI (a)synchronously using the Call by Reference or Start Asynchronous Call.