NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Passing a void* (from an allocated buffer) inside a struct to a C dll

Hello,
 
Currently testing the potential of TestStand and I am stuck on one small problem.
I have seen similar question, but no real answer (or I could not understand them)
 
The C function prototype looks like this:
 

TSDLL_API int32 TSTransfer(int32 hSystem, PIN_PARAMS_TRANSFERDATA pInData, POUT_PARAMS_TRANSFERDATA pOutData)

where the structure PIN_PARAMS_TRANSFERDATA is defined as

typedef struct

{

uInt16 u16Channel;

uInt32 u32Mode;

uInt32 u32Segment;

int64 i64StartAddress;

int64 i64Length;

void * pDataBuffer;

HANDLE *hNotifyEvent;

} IN_PARAMS_TRANSFERDATA, *PIN_PARAMS_TRANSFERDATA;

 

So,

How should the structure be represented in the Type gallery of TestStand??

How can I allocate a buffer (Array of Int8, or Int16 or Int32) and assigned it to the struct?

I would like to use a local variable that could be filled with the requested data so it could be used with further test.

 

Thanks

Eric

 

 

 

 

0 Kudos
Message 1 of 8
(4,043 Views)
If you want to pass a struct from TestStand to the C DLL you can consider creating a custom data type in the type palette and passing it through. A pointer can be cast to any data type you wish. TestStand does support the void data type to pass data.
You may also want to consider passing the void data in as an int pointer and then casting it back to a void.

Thank you
Nandini
NI
0 Kudos
Message 2 of 8
(4,020 Views)
Do you want to allocate the data buffer inside of teststand or in your dll? You have to be careful because the memory has to be deallocated by the same environment that allocated it or you could end up corrupting or leaking memory. Another issue is do you need the data to be written to and read from the buffer directly inside of teststand our only from your dll or some sort of combination of the two?

Basically if you just need teststand to hold the pointer you can just tell teststand that that field in the structure is a 32-bit integer (same size as a pointer in C) then things should work ok as long as you only access it from inside your dll (i.e. teststand can hold the value of the pointer this way, but will only see it as an integer on the teststand side).

If instead you want to be able to allocate the buffer directly in teststand and read/write to it in both teststand and your dll, then things can get more complicated, please provide more details if this is the case to explain exactly what you want to be able to do with this data type both inside of teststand and in your dll.

Also, do you already know how to define c structs in teststand or are you asking about that too or just what you should do for this particular field?

-Doug
0 Kudos
Message 3 of 8
(4,015 Views)
I already know how to define C struct in TestStand. So far, the one i needed were straightforward.

My question is really oriented toward the void* inside the struct.

In  this case, I want to create the "buffer" in TestStand, then pass it to the C dll as a void* to be filled in since the value might be Int8, Int16 or Int32 based on the input. The usage for this is to have TestStand act a the middleman (as it is supposed to) and get the data from 1 input and then use the given input in other tests, either in C or Labview.

So, I guess from the comment I read it is possible, but how? And  is it worth the trouble or are there better alternatives (easier, safer)?
I guess the same approach would be easier if instead of having a C dll to fill in the buffer, I would have a  LabView  vi  to perform the same action?

Thanks
0 Kudos
Message 4 of 8
(4,004 Views)
One idea is that you could create a separate data type for each of the possibilities and use the one that's most appropriate for a particular call (especially if the data type is based on input information which you already have before making the call). The field could be identical in all of the datatypes (i.e. an array of numbers), just the c struct info for the data type would need to be different (make sure you set its "Store As" type to Pointer to Array if you want it to map to a void * in your struct). This really only matters for your C calls as labview will always get the array of numbers as an array of numbers inside of its equivalent cluster.

Something important to keep in mind though is that if you have teststand passing in these arrays, you shouldn't be trying to reallocate them inside of your C code modules. The code modules can access the memory that teststand's allocated (the array size is the memory size), but the code module can not reallocate or free the memory.

Hope this helps,
-Doug

0 Kudos
Message 5 of 8
(3,998 Views)
Just want to add that storing a pointer as a 32-bit integer like I previously suggested could lead to trouble in the future when all the software involved has switched over to the 64-bit architecture as pointers will then be 64-bits long. So it might be best to avoid doing that. In this particular case there's probably a better solution anyway (see later posts).

-Doug

0 Kudos
Message 6 of 8
(3,993 Views)
One thing important to note when casting a void pointer to an int is that the method is ok only on 32-bit systems. This would however, create a problem on a 64-bit system. The reason is that on 64-bit systems, a coid pointer is a 64 bit value and all ints aer 32 bits. Casting 64 bit data into 32 bits can cause the problem to occur.

Thank you
Nandini
NI
0 Kudos
Message 7 of 8
(3,971 Views)
Nandini,

Just want to add that it's only a problem on 64-bit systems if you are running 64-bit software (64-bit Windows can still run 32-bit apps and TestStand is currently a 32-bit app). Anyway, this is all getting off topic. Sorry about that.

Gig52, if you still need help with the original problem, please let us know.

-Doug

0 Kudos
Message 8 of 8
(3,950 Views)