LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

dll call library function with complex data type

Hi all,

I'm working on combining labview with dll call library (manufacturer's driver) written in c++ and it will used to control measurement instrument. (Environment : Windows 10 with Labview 2021 32bit)

To control the device, I tried to use the instrument scan function in the driver which shows basic information of installed device.

In the header file of dll, driver scanning function is defined as

 

DRV_API LONG32 CALLING_CONV Drv_ScanForInstruments(INT32 *NumScanInst, INST_DESC *ScanReturn);

 

And struct of INST_DESC is defined as:

 

typedef struct INST_DESC_TAG
{
INST_HANDLE MyHandle;         //For returning to user app
Interface Interface;                      //enum hex

InstType Type;                             //enum hex
InstModel Model;                         //enum hex

PTRUINT32(phBaseAddress, PadphBaseAddress) // #define PTRINT32(name, pad) INT32 * name
PTRUINT32(vBaseAddress, PadvBaseAddress)     // #define PTRINT32(name, pad) INT32 * name

INT32 PciDeviceNumber;
INT32 PciBusNum;
INT32 PciSlotNum; //Not used
INT32 PciFunction;

#ifdef DRV_PCI_VISA
UINT8 ViInstrDescription[VI_FIND_BUFLEN]; //256 * 8 bit

ViSession ViInstrSession; //BIUINT32
#else
UINT32 Reserved1[64];
#endif
}INST_DESC;

 

In the configuration of Call Library Function, I configured NumScanInst parameter as "signed 32-bit integer" and "pointer to value".

In ScanReturn parameter, I configured type as "Adapt to Type" and data format as "Handles by Value".

 

When I ran the labview test code, I found that number of scanned instruments is three with one real device and two virtual (for simulation) devices.

And I found that in the old version code of dll, if multiple devices are found, then data is stored as array as follows.

 

ScanReturn[index].MyHandle = CreateHandle(index); 

 

But in my labview code, I could assign only one cluster which correspond to typestruct defined in header file.

My guess is that if dll has an array of data sets, then I should also assign same array for memory allocation.

Is it right? Then how can I define an array of different types of data?

And in output data, output data after 7th from the top looks assigned to different position

(it looks like 92 in PciSlotNumb should be seen at PciDeviceNumber and others following should also

move up in similar manner)

Does it come from misalignment of data? then what should I do to fix it?

 

labview_test_code.png

0 Kudos
Message 1 of 11
(1,624 Views)

Ok, a few comments:

 

- That PTRUINT32() macro is doing something more than just declaring an UINT32 element as you assumed. It is likely a definition that defines a fixed size array, with the name of the data element being the first parameter and the size of the array being the second. It's a guess but the definition for this macro must be somewhere in your library headers so you can easily check. This is also the reason for the displacement of the values in your data elements beyond these two elements.

 

- A LabVIEW array is NEVER directly equivalent to a C array pointer and even less to a fixed size array like what you have for your ViInstrDescription element. This is simply a memory area of VI_FIND_BUFLEN 8-bit elements directly embedded in the structure. The closest thing you can create in LabVIEW that matches this is a cluster containing VI_FIND_BUFLEN uint8 elements. Instead of creating such a monster you can also create an array constant of uInt8 (it can even be empty) on the diagram, then pass that through a Cluster to Array node, right click on that node and enter 256 in the dialog. Now you have a wire that represents a fixed size array of 256 uInt8 elements and can wire that into your bundle node at the right place.

 

- Once you have that you can create an array of this whole cluster by using the Initialize Array function. Wire the number of elements you want to the according terminal of this function and wire the same value also to the left terminal for the NumScanInst parameter. Configure the second parameter as Adapt to Type, Pass Array Data Pointer. After the function returns, use the value returned in the NumScanInst parameter to resize the array to the number of elements indicated by this variable. Dissect the array elements as you want. 

Rolf Kalbermatter
My Blog
0 Kudos
Message 2 of 11
(1,572 Views)

Dear Rolf,

Thank you for your kind reply

I checked the header file and found that it was defined as follows

 

#ifndef 64BIT
#define PTRINT32(name, pad) INT32 * name; void * pad;
#else
#define PTRINT32(name, pad) INT32 * name;
#endif

 

which makes difference for 64bit compiling.

 

- A LabVIEW array is NEVER directly equivalent to a C array pointer and even less to a fixed size array like what you have for your ViInstrDescription element. This is simply a memory area of VI_FIND_BUFLEN 8-bit elements directly embedded in the structure. The closest thing you can create in LabVIEW that matches this is a cluster containing VI_FIND_BUFLEN uint8 elements. Instead of creating such a monster you can also create an array constant of uInt8 (it can even be empty) on the diagram, then pass that through a Cluster to Array node, right click on that node and enter 256 in the dialog. Now you have a wire that represents a fixed size array of 256 uInt8 elements and can wire that into your bundle node at the right place.

 

 : I tried to follow your comment in LabVIEW block diagram. Then how can I make an array constant inside the cluster? I tried to put an uint8 constant inside the cluster and wired it to Cluster to Array node. But in the right click on that node(Cluster to Array node), I couldn't find any dialog to enter 256.

 

 

 

5e474964-6179-48d7-a64f-aea4f2fa75ac.png

In upper diagram, LabVIEW does not crash(parameter is set to array data pointer) but I could not see any output data.

 

What part is wrong in my block diagram? I guess there is something missing in my diagram.

 

Thank you

0 Kudos
Message 3 of 11
(1,554 Views)

I realize that I made an error. It should not be Cluster to Array Node but rather Array to Cluster Node. Sorry for the confusion.

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 11
(1,542 Views)

Thank you Rolf.

I made a labview and it looks working with my dll.

Test_result2.png

I have an additional question about labview shown above.

I made an array from cluster and data is unbundled after output of dll.

In this case, how can I access data in other array or cluster?

In upper diagram, I can only access MyHandle of only one cluster.

But I want to check value of MyHandle of different cluster at the same time.

Should I get whole data as an array of dimension 3?

Thank you.

0 Kudos
Message 5 of 11
(1,486 Views)

Try to move with the curser over the lower border of the Index Array function. Grab the handle and pull it down!

 

This is basic LabVIEW knowledge. You shouldn’t even dare to use the Call Library Function node before having done the basic tutorials where you learn that! 😀

 

But before you can expect in those array elements to be anything present, you also need to tell the function that you actually pass in an array that has 3 elements, by adjusting the NumScanInst constant accordingly, but make sure you NEVER EVER make this number larger than the actual array size you initialized!

And after the function returns, the right side of that terminal returns the number of records the function actually filled in. It can be less than the number you actually allocated!

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 11
(1,477 Views)

You also need to remove that Reserved element in the cluster. This is a conditional compile element, either the compiler needs to use the ViInstrDescription and VIInstrSession element OR the Reserved element. Unfortunately the programmer who wrote that made an error too. The size of the ViInstrDescription + VISession element don't add up to the same size as the Reserved element, so the whole exercise of trying to make this structure the same size independent of how it is compiled is useless. If the DLL was compiled to use VISA it uses 4 more bytes per array element than when it wasn't compiled as such.

Rolf Kalbermatter
My Blog
0 Kudos
Message 7 of 11
(1,445 Views)

Dear Rolf,

Thank you for your kind reply.

Test_result3.png

I have modified the labview code as I understand what you commented on. It works fine and I can get the value what I wanted.

Then, is there any way to extract only MyHandle's from these three clusters without accessing

each cluster one by one?

Although this diagram only shows clusters from one instrument, in the future, I need

three or more instruments and number of clusters will also increase. Therefore, rather than accessing every cluster one by one, I want to know how to extract values of one variable from all clusters.

 

And your comment is right. In this case, I can see how many instruments are installed and respond manually. But if system setting is changed, I should change the diagram before after output of dll (such as number of clusters which corresponds to number of instruments). I hope to get a solution to automate those processes.

0 Kudos
Message 8 of 11
(1,432 Views)

You also need to remove that Reserved element in the cluster. This is a conditional compile element, either the compiler needs to use the ViInstrDescription and VIInstrSession element OR the Reserved element. Unfortunately the programmer who wrote that made an error too. The size of the ViInstrDescription + VISession element don't add up to the same size as the Reserved element, so the whole exercise of trying to make this structure the same size independent of how it is compiled is useless. If the DLL was compiled to use VISA it uses 4 more bytes per array element than when it wasn't compiled as such.

 

: Thank you for your kind comment.

I also wonder why those elements in a structure has different size. I'll ask manufacturer's engineer to change that code. Thanak you.

0 Kudos
Message 9 of 11
(1,431 Views)

Do some tutorials! I'm not going to explain basic LabVIEW things here. Before you even start dealing with Call Library Nodes at all, you should have done exercises about arrays, loops, autoindexing of arrays on loop bounderies, and many more things. I'm really serious. Right now you try to repair a rocket engine but still haven't finished your basic mechanical education.

Rolf Kalbermatter
My Blog
0 Kudos
Message 10 of 11
(1,425 Views)