05-27-2011 06:32 AM
Hello!
I've just read the topic "invalid .NET reference" which has a relation to my question, but still doesn't covers it completely.
I have a .NET assembly in a form of a DLL written by another software developer. In a TestStand sequence I create a reverence to an object from this .NET assembly and use this reference throug the sequence or also in the subsequences passing this reference as a parameter to a subsequence.
But: when I want to pass this reference to a VI, which I also want to call in the sequence I get an error by loading this VI. I have made a VI which needs as an input 2 references to .NET objects created "somewhere" - e.g. by the calling VI. It works well in the LabView, but I can't even load such VI into TestSr´tand. I attach a picture showing an error.
Does it mean - as I read in the topic "invalid .NET reference" - that it is impossible to pass a .NET reference between the appdomains?
For me the work out is to repeat the initialisation of .NET object within VI, which costs memory because VI shall be called several times in the test sequence.
Or is there any trick to persuade TestStand to pass .NET object reference to the VI? I have already tried to use "Variant to .NET", but this way is not accepted by the VI - it doesn't recognize the reference :-(.
I would be thankful for any ideas how to pass .NET object reference from TestStand to a LabView VI (or for a confirmation from a specialist that it is impossible im principle).
Solved! Go to Solution.
05-27-2011 10:39 AM - edited 05-27-2011 10:41 AM
Unfortunately, it is not currently supported to share .NET references between the TestStand .NET adapter and LabVIEW. TestStand and LabVIEW currently each create their own appdomains in which they load and run .NET assembly code. You can pass .NET references from LabVIEW into TestStand and store them in Object Reference variables and pass them back into other VIs, but you can't use those references with the TestStand .NET adapter. Similarly, references you create with the TestStand .NET adapter cannot be used directly by LabVIEW.
It's not impossible to pass a reference from one appdomain to another, so it theoritically is possible to pass a reference from an object in TestStand's appdomain to code running in LabVIEW's appdomain, but it's also quite complicated to do this and requires that your .NET objects be derived from MarshalByRefObject or be serializable (in which case a copy is actually made in the other appdomain). .NET remoting is the mechanism with which this can be done.
Another option is to expose your .NET code as a COM server (see msdn for documentation on various ways to do this) as COM objects can be more easily shared between TestStand and LabVIEW.
Or if there is a simpler way to accomplish what you are trying to do such that you do not really need to share the objects between TestStand and LabVIEW, I'd probably recommend that instead. Perhaps if you explain in more detail what sort of objects you are wanting to access from both TestStand and LabVIEW and why, I could perhaps help make some suggestions.
Hope this helps,
-Doug
05-29-2011 03:48 AM
Hi, Doug!
Thank you for the answer. I read from it a possibility to try a reverced way: first create a .NET object in a LabView appication and then use this reference in Test Stand sequence and again by LabView application - is it what you advice? I also noticed your advice from another topic, that the VI should not be uloaded after execution. I'll try to do this .
Some more details about my goal and .NET references which I hae to use.
We test an object (on-board softwae) by stimulating it by commands and getting a respons over a socket.Commands are 16-bit word packets, coded accorting given rules (protocol). Response are also 16-bit packets coded after given rules. A user doing a test is interested in getting and evaluating decoded items, say, not 16-bit word, by physical parameter - e.g. temperature in C°, or voltage in V. the rules, how to interprete a 16-bit word in a data packet or how to
put a physical parameter nto a command packet are put in a protocol. A protocol may change - these changes shall be transparen for the user.
.NET assembly written for our usage in Test stand and LabView loads this protocol from a data bases and possesses methods and properties, which are called to code or decode packets received/sent during a test sequence. The protocol is ca. 50 MB large. That's why it makes sense to load it once at the Setup phase of a test stand sequence , get a reference to it and use it at different places in subsequences. It goes well for coding packets and sending commands. For packet reception there is a LabView VI, which collects packetitems - it analyses received packets and selects only what user wanted to get. Due to the fact, that the reference to -NET object - decoding protocol - cant' be passed to this VI , it initialises the protocol once more, loding 50 MB again. The VI has to be called seeral times in a sequence - and you see what happens, the memory is exausted.
One could replace VI by calling .NET methods direct from a test stand sequence, but VI conains not only collecting of packets but also analyze, which makes test stand sequence rather complicated (to code all "for"s and "while"s in a seq.
.NET assembly is used "thru" in other application, especially in C, that's why I suppose, that to change to COM would destroy the system - it was just the adantage of the usage of one and the same method for one and the same data base through the whole project.
That's about the goal. I'll think over how I can apply your suggestion and let you know.
Regards
05-29-2011 03:48 AM
Hi, Doug!
Thank you for the answer. I read from it a possibility to try a reverced way: first create a .NET object in a LabView appication and then use this reference in Test Stand sequence and again by LabView application - is it what you advice? I also noticed your advice from another topic, that the VI should not be uloaded after execution. I'll try to do this .
Some more details about my goal and .NET references which I hae to use.
We test an object (on-board softwae) by stimulating it by commands and getting a respons over a socket.Commands are 16-bit word packets, coded accorting given rules (protocol). Response are also 16-bit packets coded after given rules. A user doing a test is interested in getting and evaluating decoded items, say, not 16-bit word, by physical parameter - e.g. temperature in C°, or voltage in V. the rules, how to interprete a 16-bit word in a data packet or how to
put a physical parameter nto a command packet are put in a protocol. A protocol may change - these changes shall be transparen for the user.
.NET assembly written for our usage in Test stand and LabView loads this protocol from a data bases and possesses methods and properties, which are called to code or decode packets received/sent during a test sequence. The protocol is ca. 50 MB large. That's why it makes sense to load it once at the Setup phase of a test stand sequence , get a reference to it and use it at different places in subsequences. It goes well for coding packets and sending commands. For packet reception there is a LabView VI, which collects packetitems - it analyses received packets and selects only what user wanted to get. Due to the fact, that the reference to -NET object - decoding protocol - cant' be passed to this VI , it initialises the protocol once more, loding 50 MB again. The VI has to be called seeral times in a sequence - and you see what happens, the memory is exausted.
One could replace VI by calling .NET methods direct from a test stand sequence, but VI conains not only collecting of packets but also analyze, which makes test stand sequence rather complicated (to code all "for"s and "while"s in a seq.
.NET assembly is used "thru" in other application, especially in C, that's why I suppose, that to change to COM would destroy the system - it was just the adantage of the usage of one and the same method for one and the same data base through the whole project.
That's about the goal. I'll think over how I can apply your suggestion and let you know.
Regards
05-30-2011 06:06 AM
Hi, Doug,
I tried to initialize .NET object in a VI, make a reference to this object as VI output and load this VI in a test Stand sequence. The result was negative, exactly as before, when I tried to pass a reference to a .NET object to VI: it was a "load error" saying that the connectors don't match parameters. I decided to use initialization within VI by every call - the memory grows, but there is no choice. Does "Dispose" method works correctly? I have an impression, that it makes no great difference if i use "Dispose" by closing of VI or not.
I'll pass your answer concerning methods of writing of .NET assemby to collgues who deal with the subject.
Thank you for help.
Regars
06-01-2011 10:12 AM - edited 06-01-2011 10:13 AM
As doug mentioned, one of the ways around this is to create a shared object with .NET Remoting.
Here is an example program that shows you how to do this:
Sharing .NET Objects Between TestStand and LabVIEW using .NET Remoting
06-01-2011 12:23 PM
pericles,
Did you try refreshing the prototype in your teststand step? Are you getting that error at edit time or runtime?
Dispose is not something that all objects support. The .NET objects you are using must explicitly implement support for this if they need it.
-Doug
06-02-2011 03:56 PM
Thank you for the tip - I'll try it. Or I'll send it to a .NET assembly developer (it's not me)
06-02-2011 03:59 PM
Yes I did. The error is in the edit mode: I can't load a VI, it doesn't go so far that a sequence may be started. The assembly which I use included "Dispose()" method. Of course it is still a question if the developer has properly implemented it.
06-03-2011 10:08 AM
When you change the prototype of a VI that is already specified in TestStand, you either need to refresh the prototype for the already specified step in TestStand, or you need to run the "Update VI Calls" tool from the Tools menu item on the sequence file containing the step.
Hope this helps,
-Doug