LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How can I pass the adress of a cluster to a dll

Hi,

I need to pass the adress of the struct(cluster) below from labview 7.1 to a dll written in C++.
Can anyone help ?

typedef struct
{
unsigned char DPV1_Supported;
unsigned char Max_Channel_Data_Length;
unsigned char Extra_Alarm_SAP;
unsigned int C1_Response_Timeout;
unsigned char NormParameters [7];
unsigned char UserParamLength;
unsigned char UserParameters [248];
unsigned char ConfigLength;
unsigned char Configuration [256];
unsigned char OutputLength;
unsigned char OutputData [256];
unsigned char InputLength;
unsigned char InputData [256];
unsigned char NormDiagnosis [6];
unsigned char UserDiagLength;
unsigned char UserDiagnosis [256];
BOOL bCommunicate;
BOOL bOperate;
BOOL bNewDiag;
} DP_DATA;


Thanks,

Andreas
0 Kudos
Message 1 of 5
(3,626 Views)
Place the cluster on your front panel
Place a CALL LIBRARY function on your diagram.
Pop up on the CALL LIBRARY, and fill in the DLL name and path and function name.
Set the RETURN TYPE to whatever the DLL has to send back.
Add a PARAMETER AFTER.
Set its TYPE to ADAPT TO TYPE.
Notice your prototype declaration down below - it's a void *.

That is a pointer to the cluster.


Be aware, though that you cannot have the structure you declared in LabVIEW without special effort. LabVIEW arrays and C arrays are two distinct beasts. You can't simply put an array inside a cluster and have the declaration you gave be correct.
Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

Message 2 of 5
(3,615 Views)
Hi CoastalMaineBird,

thanks for your anwser.
Here is the the complete prototype of the function in the dll:

long DPReadSlaveData(unsigned char ucSlvAddr, DP_DATA FAR * pDpData, BOOL bResetDiag)
The adress of the struct which I want to pass respects only to the second argument.


Can you explain me the difference between LabView arrays and C arrays more detailed. Why I can't put an array inside a cluster....
How is the correct usage?

Thanks,

Andreas
0 Kudos
Message 3 of 5
(3,593 Views)
Can you explain me the difference between LabView arrays and C arrays more detailed.

A C array of THINGs is a pointer to a THING. The THING is followed in memory by another THING, etc., etc.
There is no difference between a pointer to a THING and an array of THINGs, (except the expectation of the user is that the array contains more than one THING). But physically, they are both pointers to a THING.

In C, if you pass an array to some function which operates on it, you also have to have some convention to separately pass the number of items in the array. The array itself has no way of indicating its own size. A C string is terminated by a null byte - that's one way. Other functions require you to pass a separate parameter to indicate how many elements are in the array.


A LabVIEW array is a different beast. It is a HANDLE, not a pointer. When you resolve the handle, you interpret the first 4 bytes as an I32 with the current dimension size in it. If you have a 2-D array, you interpret the first TWO I32s as the current dimension size. If you have a 3-D array, you interpret the first THREE I32s, etc. etc.
Immediately after the dimension size(s), follows the data itself.

Read this for the official explanation. It's a good idea to print this out and keep it around.

http://zone.ni.com/devzone/conceptd.nsf/webmain/370DFC6FD19B318C86256A33006BFB78?opendocument target=_blank


Why I can't put an array inside a cluster
I didn't mean to imply that you can't do that. You can. LabVIEW will handle it correctly. But you can't pass the cluster to C and have it understood, using ordinary C array declarations.

It's legal in LabVIEW to have a cluster with an I32 followed by an array of DBLs, for example.
But if you pass that thing to a DLL or CIN, what gets passed is a pointer to an 8-byte chunk of memory.
The first four bytes are the I32 value. The second four bytes are a HANDLE to the array data. The handle points to a pointer, the pointer points to a chunk of memory, the first four bytes of that chunk are the dimension size.

The bottom line is you can't treat it as an array in LabVIEW, and also as an array in C.

You have three choices:

1... Change the C code to understand LabVIEW arrays. There are lots of library tools to help you deal with LabVIEW arrays.

2... Change the LabVIEW code to fake the structure that C requires. If you have an array of 256 Bytes, you'll have to fake that with a CLUSTER of 256 U8s. If you have an array declared as int[123]. you'll have to make a CLUSTER of 123 I32s. You can make the data fit the C declaration, but you have to study the details.

3... Duplicate the functionality of your C code in LabVIEW.

Hope that helps.
Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

Message 4 of 5
(3,583 Views)
Hi CoastalMaineBird,

we have solve the problem.

We use an u8 array in place of the cluster.
The first three elements of the array are u8 dummy variables.
Furthermore we have split the variable "unsigned int C1_Response_Timeout"(u16) in two u8 elements.

Thanks for your help.

Andreas
0 Kudos
Message 5 of 5
(3,550 Views)