NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Get array of unknown size from CVI code module

Solved!
Go to solution

I'm creating a custom type for my customer, and I've run into an issue that I'm not quite sure how to solve.

Here's the situation:

 

We have a custom step in which the primary code is run inside a post-step substep. The code acquires samples from an instrument, but it is unknown how many samples will be returned. The CVI function has as parameters an array, the size of that array, and an output parameter that says how many samples were returned.

void AcquireSamples (double* samples, int samplesBufferSize, int *numSamplesRetrieved)

 The goal is to have the returned array have the size of the number of samples retrieved.

 

I've tried multiple ways of doing this, none of which works completely. The issue is that as described here, TestStand creates a temporary array to pass to the code module; but it does not resize the TestStand array property. So I need to resize the array property manually, and I haven't figured out an elegant way to do that.

 

This would be easy if I were just creating a step, because I could use post-expressions. But I'm creating a type, and I don't have that luxury (my code needs to allow the customer to enter post expressions, but then I run the risk of my customer deleting any default post-expression I enter).

 

First question:

I noticed when I was creating a step with a CVI code module, that additional results allowed me to specify logging the parameters both [in] and [out]. From this I extrapolated that the expression for the parameter was evaluated both before calling the function, and again after calling the function. I did some tests, and it does seem to work that way.

 

1) Is this expected behavior? I don't see it documented anywhere, so can I rely on it staying the same in future versions of TestStand?

 

I used that behavior to my advantage to create an expression that does what I need for a code module of a step. But it doesn't work for a code module of a post-step.

 

I made a small test DLL and sequence file which illustrate my problem. I've tried to document the sequence file to show where I'm stuck. You'll need to put the DLL in one of your search directories for the custom type to work.

 

Any help would be greatly appreciated!

Josh W.
Certified TestStand Architect
Formerly blue
0 Kudos
Message 1 of 7
(4,939 Views)

Hi Josh,

Maybe I am totally off course here but can you simply just set the array in TestStand as empty and then it should take the size of the array passed to it. I have done this when passing arrays of unknow sizes from LabVIEW to TestStand.

 

Regards,

Shane.

 

0 Kudos
Message 2 of 7
(4,910 Views)

Shane,

 

Please run the example I attached.

 

In it you can see that the LabVIEW behavior is what I desire, but I cannot figure out how to get that behavior using CVI code.

 

-Josh

Josh W.
Certified TestStand Architect
Formerly blue
0 Kudos
Message 3 of 7
(4,902 Views)

I'll take a look at your example, but why not just pass in the array as a CAObjHandle and set it programmatically? That would give you full control without having to do anything tricky in an expression.

 

-Doug

0 Kudos
Message 4 of 7
(4,880 Views)
Solution
Accepted by topic author Josh_W

I think the problem is that the C programming language does not provide enough information for a caller to know what the size of an output array is in any sort of standard way. Again, I recommend you pass a CAObjHandle that is the array variable instead and set the array directly using CA_Array1DToSafeArray() to create a safearray and SetValVariant on the propertyobject which is the array property to set the array. Don't forget to free the array (using CA_SafeArrayDestroy()) you created with CA_Array1DToSafeArray after calling SetValVariant in order to avoid leaks.

 

Hope this helps,

-Doug

Message 5 of 7
(4,878 Views)

Doug,

 

Unfortunately, I'm working under the constraint that our customer wants the functions that we write to be able to be called by programmers using C, in addition to being used as the module for a TestStand post-step.

 

I was hoping that there was some magic way to just get this to work; but if there's no standard, TestStand doesn't know what magic to perform. To comply with the customer's requirements, I'll write the resizing of the array as a separate expored function from the DLL and call it as a second post-step substep. That way I can reuse it in multiple steps.

 

Thanks for the step-by-step explanation for what I need to do!

Josh W.
Certified TestStand Architect
Formerly blue
0 Kudos
Message 6 of 7
(4,865 Views)

@Josh_W wrote:

Doug,

 

Unfortunately, I'm working under the constraint that our customer wants the functions that we write to be able to be called by programmers using C, in addition to being used as the module for a TestStand post-step.

 

I was hoping that there was some magic way to just get this to work; but if there's no standard, TestStand doesn't know what magic to perform. To comply with the customer's requirements, I'll write the resizing of the array as a separate expored function from the DLL and call it as a second post-step substep. That way I can reuse it in multiple steps.

 

Thanks for the step-by-step explanation for what I need to do!


Or perhaps just write a wrapper around the C function that takes a CAObjHandle for the array and does the conversion to what the other C function expects.

 

-Doug

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