NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Accessing properties from an Object Reference

I have a binary file that was created by a .net application.  The file was created using binary serialization.  This file contains relevant data needed at runtime in Teststand when running product.  We have a lot of experience interfacing TestStand with Labview, but not so much with .net.  I will first explain what I want to do and then how I achieved it.  What my question is, is this how TestStand was intended to interface with .NET, or am I missing some key features that make this process a bit simpler?  Here's what I did:

 

1. ) Added a .Net Adapter Action step and constructed an empty object.  Assigned the returned object as an Object Reference variable.

2. ) Added a .Net Adapter Action step and called a method passing parameters to deserialize the correct file into memory.  The empty object from the previous step was also passed in as a parameter, and the called method populates it with data.

3. ) Added six additional .Net Adapter Action step, each one referencing a property of the existing object reference and assigning the value to a local variable.

 

This takes 8 test steps to complete this task.  That seems way more than it needs to be.  Do I need to have to pull out each property value?  It seems like there should be a way to simply refer to a object reference's property much like you would refer to Step.Result.PassFail.  Am I missing something?

0 Kudos
Message 1 of 7
(7,641 Views)

Hi bobopolis,

 

Maybe I am missing something but why can't you just use one .net application that pulls in the data you to pass from TestStand and then output the 6 local variables?  You could do all the processing on the .NET side of things and then pass the six properties to local variables?  Do you need the object reference in memory on the TestStand side of things?  If so just do your first two action steps then have one .NET module that outputs the six different properties of this object reference.

Peter T
Applications Engineer
National Instruments
0 Kudos
Message 2 of 7
(7,592 Views)

Currently I have only the one .net application, and all I want to do is get the values of the 6 properties and store them as local variables.  How can this be done as a single step?  It seems I have to have a seperate action step for each get.  This is what I'm trying to avoid.  Is there a way to access each property and assign them to variables as a single step?

 

 

0 Kudos
Message 3 of 7
(7,541 Views)

@bobopolis wrote:

I have a binary file that was created by a .net application.  The file was created using binary serialization.  This file contains relevant data needed at runtime in Teststand when running product.  We have a lot of experience interfacing TestStand with Labview, but not so much with .net.  I will first explain what I want to do and then how I achieved it.  What my question is, is this how TestStand was intended to interface with .NET, or am I missing some key features that make this process a bit simpler?  Here's what I did:

 

1. ) Added a .Net Adapter Action step and constructed an empty object.  Assigned the returned object as an Object Reference variable.

2. ) Added a .Net Adapter Action step and called a method passing parameters to deserialize the correct file into memory.  The empty object from the previous step was also passed in as a parameter, and the called method populates it with data.

3. ) Added six additional .Net Adapter Action step, each one referencing a property of the existing object reference and assigning the value to a local variable.

 

This takes 8 test steps to complete this task.  That seems way more than it needs to be.  Do I need to have to pull out each property value?  It seems like there should be a way to simply refer to a object reference's property much like you would refer to Step.Result.PassFail.  Am I missing something?


1) What kind of serialization are you talking about? TestStand or .NET? Serialization is a very generic term.

2) Are these TestStand or .NET properties you are trying to get? Are you trying to convert a .NET data structure into a TestStand data structure? If so you should probably use structs instead. If you create a .NET struct with all of the data you want to pass to teststand, you will see all of that data as an expandable parameter when calling a method that takes or returns such a struct. Additionally, you can create a custom data type in teststand that can automatically map to and convert back and forth between the struct.

 

Please be more specific about what you are trying to do and I will likely be able to recommend a simpler alternative. Hope this helps,

-Doug

0 Kudos
Message 4 of 7
(7,532 Views)

@bobopolis wrote:

Currently I have only the one .net application, and all I want to do is get the values of the 6 properties and store them as local variables.  How can this be done as a single step?  It seems I have to have a seperate action step for each get.  This is what I'm trying to avoid.  Is there a way to access each property and assign them to variables as a single step?

 

 


Why not just create one method in your .NET assembly that returns all 6 values (and possibly even an already populated .NET object if you need that for some reason)? That seems like the most straightforward way to get 6 values back into teststand, create a method with 6 output parameters. If this does not make sense for your use case, please explain your use case in more detail.

 

-Doug

0 Kudos
Message 5 of 7
(7,530 Views)

The .net application is a stand alone application that defines a configuration profile for a given sales order.  A user of this application will define what software part numbers are to be programmed as options into the UUT and saves this file to disk via serialization (.net serialization if not clear).  The same .net application also contains a method that if given the sales order, will find the appropriate file and return an object entity representing the configuration profile.  This profile has data such as the part number the customer ordered, the part hierarchy that maps to the appropriate UUT to be programmed, the system software p/n to be installed, and a list of software option p/n's to be installed.

 

The Test Stand sequence is a generic sequence, handling the common tasks that all products that run on this station require.  This sequence will then dynamically call the product specific sequence as they will greatly vary depending upon product.  I'm putting this data in a container, because it will be needed at the generic level and also at the product sequence level.  For example, the number of p/n's in the hierarchy will determine how many SN's it will prompt the user for.  This is handled at the generic level. The actual SW p/n's defined in the profile are meaningless at the generic level but would be passed as a parameter to the product specific sequence which would know how to handle them.  I simply pass the entire container as a parameter.  Perhaps someday in the future this could be designed differently so that all the common tasks are in a process model, but that is not in the scope at this time.

 

Because the .net dll provides this data as an entity class structure, these fields are properties.  I would think there would be a way to grab the object and reference its properties in Test Stand as simply as referencing a test stand variable, but if that can be done, I haven't found a way to do it.  Instead, I found I could get each property but at the cost of an Action step for each one, where I could then assign it to the container.

 

Being the .net application is a stand alone app built following after object oriented design principles, the data is represented as a object entity.  I do own the code so I could create a specific method that 'caters' to Test Stand, but that would seem less than desired because I would be modifying the code for no relevent purpose to the application itself.  Also, what if this was third party and I couldn't change the code? 

 

Please be easy on your answer.  A simpler way to interface a .net object might be a very basic thing to do and I'm just not aware of it.  I already have this working, and it just seems to me that Test Stand would have better support for accessing a .net class' properties.

0 Kudos
Message 6 of 7
(7,517 Views)

@bobopolis wrote:

The .net application is a stand alone application that defines a configuration profile for a given sales order.  A user of this application will define what software part numbers are to be programmed as options into the UUT and saves this file to disk via serialization (.net serialization if not clear).  The same .net application also contains a method that if given the sales order, will find the appropriate file and return an object entity representing the configuration profile.  This profile has data such as the part number the customer ordered, the part hierarchy that maps to the appropriate UUT to be programmed, the system software p/n to be installed, and a list of software option p/n's to be installed.

 

The Test Stand sequence is a generic sequence, handling the common tasks that all products that run on this station require.  This sequence will then dynamically call the product specific sequence as they will greatly vary depending upon product.  I'm putting this data in a container, because it will be needed at the generic level and also at the product sequence level.  For example, the number of p/n's in the hierarchy will determine how many SN's it will prompt the user for.  This is handled at the generic level. The actual SW p/n's defined in the profile are meaningless at the generic level but would be passed as a parameter to the product specific sequence which would know how to handle them.  I simply pass the entire container as a parameter.  Perhaps someday in the future this could be designed differently so that all the common tasks are in a process model, but that is not in the scope at this time.

 

Because the .net dll provides this data as an entity class structure, these fields are properties.  I would think there would be a way to grab the object and reference its properties in Test Stand as simply as referencing a test stand variable, but if that can be done, I haven't found a way to do it.  Instead, I found I could get each property but at the cost of an Action step for each one, where I could then assign it to the container.

 

Being the .net application is a stand alone app built following after object oriented design principles, the data is represented as a object entity.  I do own the code so I could create a specific method that 'caters' to Test Stand, but that would seem less than desired because I would be modifying the code for no relevent purpose to the application itself.  Also, what if this was third party and I couldn't change the code? 

 

Please be easy on your answer.  A simpler way to interface a .net object might be a very basic thing to do and I'm just not aware of it.  I already have this working, and it just seems to me that Test Stand would have better support for accessing a .net class' properties.


Thank you for this clear explanation. Sorry if my previous response seemed harsh in any way. I understand your use case a lot better now. Unfortunately there is no built-in way to get multiple .NET properties in a single step from a .NET class reference unless it is a byvalue type (i.e. a struct in C#). Some alternative ideas you might prefer to what you are currently doing:

 

1) use a byvalue type (i.e. .NET struct) instead of a reference type for the object containing the properties. If you do that you can use TestStand struct passing to either get all of the fields of the struct in one step, or to create a corresponding TestStand custom data type that the .NET struct maps to and that you can pass as the parameter to store all of the data in in one teststand step.

or

2) Create an assembly with the following method (It doesn't have to be in the same assembly as your other code. It could be part of a utility assembly.):

        public static void GetProperties(object objectWithProperties, string[] propertyNames, out object[] results)
        {
            results = new object[propertyNames.Length];
            for(int i = 0; i < propertyNames.Length; i++)
            {
                results[i] = objectWithProperties.GetType().GetProperty(propertyNames[i]).GetValue(objectWithProperties, new object[0]);
            }
        }

You can then use this from TestStand as a property getter that can get multiple properties from any .NET object reference in one step as follows:


forum.png 
 

Hope this helps,

-Doug

Message 7 of 7
(7,502 Views)