NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

API testStand for ModuleAdpater DotNet

Juergen -

 

The GetContstructorMetadataToken() method in my example assembly uses Type.GetConstructor() method to get a reference to the appropriate constructor. In particular, it uses the GetConstructor(Type[] types) implementation where types is an array that contains the Type of the parameters in the order in which the parameters appear in the Constructor prototype.

 

In my example, the Constructor prototype consists of a string parameter so I use the typeof(string) to get the string Type (System.String).

 

For the example you've provided for a constructor with the prototype MyClass(SequenceContext, string, int), you could create a Type array and pass it to the GetConstructor(Type[] types) method as shown below:

 

Type[] constructorParamInfo = new Type[3];

constructorParamInfo[0] = NationalInstruments.TestStand.Interop.API.SequenceContext;

constructorParamInfo[1] = System.String;

constructorParamInfo[2] = System.Int32;

myCnstrctrInfo = myAssemType.GetConstructor(constructorParamInfo);

 

Please Note that in order to use the NationalInstruments.TestStand.Interop.API.SequenceContext Type, you must reference the NationalInstruments.TestStand.Interop.API.dll assembly within the GetMetadataToken.dll assembly.

 

I hope this helps and answers your question.

Message Edited by Manooch_H on 01-06-2010 01:48 PM
Manooch H.
National Instruments
0 Kudos
Message 21 of 42
(1,942 Views)

Hi Mannoch,

 

Thanks for your answer. The solution you have pointed is well, i would done it in the same way as you, if i do it for only one constructor

But my question is how to make GetContructorMetadataToken(... Type[] myTypes) public to TestStand. 

The aim is to make it multifunctional. Assume you like to use the function for many other constructors.

So it must controlled by TS. I do not know who to create a Type[] in TS, but i assume this is impossible.

Maybe a container could do it.

 

Juergen 

--Signature--
Sessions NI-Week 2017 2016
Feedback or kudos are welcome
0 Kudos
Message 22 of 42
(1,939 Views)

Juergen -

 

I understand what you are trying to do now. This is something that I originally attempted to implement in the example I provided. The best way of doing this would be through the use of an array of strings.

 

The GetConstructorMetadataToken() method would take an additional string[] parameter:  GetConstructorMetadataToken(string assemPath, string fullClassName, string[] paramTypes)

 

From TestStand, you would pass an array of strings. So, you would call

 

GetConstructorMetadataToken(Locals.assemPath, Locals.fullClassName, Locals.paramArray)

 

where Locals.paramArray = {"SequenceContext", "string", "int"}

 

Then, within the GetConstructorMetadataToken() method, you could use Type.GetType(string typeName) as follows:

 

.

.

.

Type[] constructorParamInfo = new Type[paramTypes.Length];

for(int i = 0; i++; i < paramTypes.Length)

{

     constructorParamInfo[i] = Type.GetType(paramTypes[i]);

}

myCnstrctrInfo = myAssemType.GetConstructor(constructorParamInfo);

.

.

.

 

I decided not to provide this exact implementation in my original example because it is possible that a Type may not be loaded in which case I believe the Type.GetType(paramTypes[i]) call will not execute correctly. For example, if the NationalInstruments.TestStand.Interop.API.dll assembly is not referenced in the GetMetadataToken.dll assembly, I don't think calling Type.GetType("SequenceContext") will properly execute.

 

This is why I made the following note in the post of my original example:

 

Note that the implementation of the GetMetaDataToken.dll that I've provided is very simplistic and specific to the example that I've created. Modifications will need to be made to make the implementation more robust and capable of handling the caveats I mentioned in the previous bullet. Also, you will have to update some of the hard-coded paths to match the paths on your machine. 

 

Hope this helps.

Message Edited by Manooch_H on 01-06-2010 02:36 PM
Manooch H.
National Instruments
Message 23 of 42
(1,936 Views)

Hi Mannoch,

 

You are right Type.GetType(string) is the trick.

for my example i have used instead a TS local a string[] to be independent of TS (so i can use it in some other code 🙂 )

 

 public int GetConstructorMetadataToken(string assemPath, string fullClassName, string[] strArrayType)

{

ConstructorInfo myCnstrctrInfo;

int metadataToken = -1;

Assembly myAssem = Assembly.LoadFrom(assemPath);

Type[] types = myAssem.GetTypes();

Type myAssemType = myAssem.GetType(fullClassName);

Type[] constructorParamInfo = new Type[strArrayType.Length];

for(int i=0; i < strArrayType.Length; i++)

{

constructorParamInfo[i] =
Type.GetType(strArrayType[i]);

}

myCnstrctrInfo = myAssemType.GetConstructor(constructorParamInfo);

metadataToken = myCnstrctrInfo.MetadataToken;

return metadataToken;

}

 

To use SequenceContext you have to use the AssemblyQualifiedName

for TS4.0 it looks like that: "NationalInstruments.TestStand.Interop.API.SequenceContext, NationalInstruments.TestStand.Interop.API, Version=4.0.0.326, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8"

 

 

Juergen

--Signature--
Sessions NI-Week 2017 2016
Feedback or kudos are welcome
0 Kudos
Message 24 of 42
(1,922 Views)
Glad I was able to help Juergen.
Manooch H.
National Instruments
0 Kudos
Message 25 of 42
(1,921 Views)

Hi Manooch,

 

I think I only need to have the MetadataToken of the Method to add parameters.

 

So I would like to transform your .Net method to Labwindows CVI because all my program is writted with CVI :

 

public int GetMethodMetadataToken(string assemPath, string fullClassName, string methodName) { MethodInfo myMthdInfo; int metadataToken = -1; Assembly myAssem = Assembly.LoadFrom(assemPath); Type myAssemType = myAssem.GetType("myTestAssembly.Class1"); myMthdInfo = myAssemType.GetMethod(methodName); metadataToken = myMthdInfo.MetadataToken; return metadataToken; }

 So i get this in Labwindws CVI in including "mscorlib2.h":

long MetadataToken = 0; System_Reflection_Assembly ReflectionAssembly; CDotNetHandle ExceptionHandle; System_Type Type; System_Reflection_MethodInfo ReflectionMethodInfo; Initialize_mscorlib (); System_Reflection_Assembly_LoadFrom(sModulePath, &ReflectionAssembly, &ExceptionHandle); System_Reflection_Assembly_GetType_1(ReflectionAssembly,sClassName, &Type, &ExceptionHandle); System_Type_GetMethod_5 (Type,sFunctionName,&ReflectionMethodInfo,&ExceptionHandle); System_Reflection_MethodInfo_Get_MetadataToken(ReflectionMethodInfo,&MetadataToken, &ExceptionHandle); Close_mscorlib ();

 But i get a FATAL RUN-TIME ERROR:  The program has caused a 'General Protection' fault at 0023:004EFE37 on the function System_Reflection_MethodInfo_GetMetadataToken.

 

Have you got an idea what i do wrong?

 

Anthony

 

 

0 Kudos
Message 26 of 42
(1,860 Views)

Anthony -

 

Ideally, you would have used the CVI .NET Controller to create a library of functions that map to the methods in the provided example assembly. I have never used the functions that you are attempting to use. Whether you continue down this path, or choose to create a .NET Controller in CVI, I recommend posting the question to the CVI forums as you will likely get more knowledgeable assistance there.

 

Hope this helps.

Manooch H.
National Instruments
0 Kudos
Message 27 of 42
(1,848 Views)

Hi Manooch_H

 

I'm investigating why my code which performed very well, doesn't work now!


So, I did some tests with several versions of TestStand and I don't get the same result!

 

When I use the function TS_DotNetModuleLoadMemberInfo then the functions getParametersList and getParametersCount, the results of these functions are correct with TestStand 3.5 and 4.0. There is no problem with my code and these versions of TestStand!

From TestStand 4.0, it doesn't work then it's the same code! So I guess it is a regression? (even if the function
TS_DotNetModuleLoadMemberInfo is declared deprecated )

I also did a test with version 3.0 and then the function returns TS_DotNetModuleLoadMemberInfo error -17,500 Unknow Error.

 

Can you tell me more about these issues?

 

Anthony

0 Kudos
Message 28 of 42
(1,809 Views)

Anthony -

 

I'm confused. You say that LoadMemberInfo() works for TestStand 3.5 and TestStand 4.0. But then you claim that it doesn't work from TestStand 4.0 and on. Which is it? Does the code work in TestStand 4.0 or not?

 

I've tested the LoadMemberInfo() method in TestStand 4.0 and it doesn't behave as expected. If you have a working example of using LoadMemberInfo() in TestStand 4.0, could you post it to this thread? I would be happy to look over it.

Manooch H.
National Instruments
0 Kudos
Message 29 of 42
(1,774 Views)

... so we can get rid of the wrapper stuff,Smiley Very Happy

 

but on my maschine TS4.0 (XP  .net Framework 2.0,3.0,3.5) it is not working as suspected.

 

Juergen

 

 

Message Edited by j_dodek on 01-20-2010 04:42 PM
--Signature--
Sessions NI-Week 2017 2016
Feedback or kudos are welcome
0 Kudos
Message 30 of 42
(1,767 Views)