04-10-2014 05:37 AM
Hi All,
I import a .NET class from a dll to teststand and I saved it in a object reference that I created.
I send a message with the refernce to c# but I cannot convert it back.
I can see that the object reference on teststand that contains the .NET class is differ then "nothing" but I get null when I try to cast it back to .NET type on my C# app.
How can I convert the object reference back on my c# GUI.
Tnx
p.s I use teststand 2013
04-10-2014 09:11 AM - edited 04-10-2014 09:12 AM
.NET steps are executed in a different appdomain than your UI lives in. You can share an object across appdomains by either deriving it from MarshalyRefObject (which will allow you to directly share the object), or making it serializeable (which will cause a copy to be created). In addition, the assembly in which the types for the object reside must either be in the same directory as the exe (or in the exe itself), in the GAC, or there is another alternative involving AssemblyResolve (but I recommend you do one of the first two since they are simpler).
Hope this helps,
-Doug
04-22-2014 03:27 AM
Hi All,
Sorry but I don't understand,
Can someone show me an example how to pass a .NET object from NI to a c# application.
NI contains the object reference of the .NET object
Tnx,
04-22-2014 09:37 AM
You can use TestStand object reference variables just like you were likely doing:
MyClass myvar = (MyClass) teststandvar->GetValInterface("", 0);
The key is that MyClass either needs to be serializable (in which case a copy is made with the above line of code), or derived from MarshalByRefOject (in which case a proxy to the object is created in the UI's appdomain which forwards all calls to the object in the execution appdomain).
To make a class serializable use the [serializable] attribute, to derive from MarshalByRefObject, derive from MarshalByRefObject (it's a .NET framework class).
Hope this helps,
-Doug
04-22-2014 10:25 AM
Hi Dug,
It doesn't work for me,
On NI I send the message "RunState.Thread.PostUIMessageEx(UIMsg_UserMessageBase+101,RunState.TestSockets.MyIndex,"",Locals.GraphPane,True)"
Now, graphPane is my object the I have passed from my dll
When I get the UI message I use your code "GraphPane g = (GraphPane)propertyObject.GetValInterface("", 0);"
and nothing happens.
On NI editor I can see that the object reference contains the .NET object
I need more examples
Tnx
04-23-2014 10:13 AM
What do you mean by nothing happens? In C# a C style cast either generates an exception or succeeds. If you are getting an exception what kind of exception is it and what is the error message? Also how are you setting propertyObject? If you are passing the object in a UI message like that you need to do something like the following instead:
GraphPane g = (GraphPane)msg.ActiveXData;
The way you are passing the reference, you won't actually be passing a propertyobject, you will instead be passing the .NET reference itself. To pass the propertyobject you would have to do "&Locals.GraphPane" for the activexdata parameter, if you do that then the code would look more like the following:
GraphPane g = (GraphPane)((PropertyObject)msg.ActiveXData).GetValInterface("", 0);
Hope this helps,
-Doug
04-23-2014 10:26 AM
Hi Doug,
When I sent the message
RunState.Thread.PostUIMessageEx(UIMsg_UserMessageBase+101,RunState.TestSockets.MyIndex,"",Locals,True),
GraphPane is located on Locals
I received it on UI message event as I explained before and the exception that I get When I use the code
PropertyObject propertyObject=uiMsg.ActiveXData as PropertyObject;
GraphPane g = (GraphPane)propertyObject.GetValInterface("", 0);
is COM Exception Occured: Expected Object Reference, found Container.
04-23-2014 10:44 AM
@NewSCRUser wrote:
Hi Doug,
When I sent the message
RunState.Thread.PostUIMessageEx(UIMsg_UserMessageBase+101,RunState.TestSockets.MyIndex,"",Locals,True),
GraphPane is located on Locals
I received it on UI message event as I explained before and the exception that I get When I use the code
PropertyObject propertyObject=uiMsg.ActiveXData as PropertyObject;
GraphPane g = (GraphPane)propertyObject.GetValInterface("", 0);
is COM Exception Occured: Expected Object Reference, found Container.
Since you are passing Locals as the activexdata parameter, you need to specify the actual local variable in the lookup string to the GetValInterface call as follows:
GraphPane g = (GraphPane)propertyObject.GetValInterface("GraphPane", 0);
The way your code is written propertyObject is the Locals container itself, that is why you need to specify the subproperty as the lookupstring for GetValInterface().
Hope this helps,
-Doug
04-24-2014 12:38 AM
Hi Doug,
I have tried your example and the result is null
PropertyObject propertyObject=uiMsg.ActiveXData as PropertyObject;
GraphPane g = (GraphPane)propertyObject.GetValInterface("GraphPane", 0);
Even when I use this example without the casting he result is still null
propertyObject.GetValInterface("GraphPane", 0)
The poor solution is to create a container with the important fields and pass the object reference by UIMessage and it works well but that isn't what I'm looking for.
p.s. the object GraphPane is saved on NI Editor as an object Reference.
Tnx
04-24-2014 10:27 AM
@NewSCRUser wrote:
Hi Doug,
I have tried your example and the result is null
PropertyObject propertyObject=uiMsg.ActiveXData as PropertyObject;
GraphPane g = (GraphPane)propertyObject.GetValInterface("GraphPane", 0);
Even when I use this example without the casting he result is still null
propertyObject.GetValInterface("GraphPane", 0)
The poor solution is to create a container with the important fields and pass the object reference by UIMessage and it works well but that isn't what I'm looking for.
p.s. the object GraphPane is saved on NI Editor as an object Reference.
Tnx
What exactly is null? Again, casts don't ever result in null, you either get an error or they succeed. If you get an error please post the error message to this thread.
-Doug