From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Probel with call library function: I have a dll based on a complicated struct data type. How can I pass this structure?

The data type is
typedef enum {false, true} bool;
typedef float flt4;
typedef double flt8;
typedef int i32s;
typedef unsigned int i32u;
typedef short int i16s;
typedef unsigned short i16u;
typedef signed char i08s;
typedef unsigned char i08u;
struct t_UnwrapData {
struct {
i08u flags;
i16u unwrap_m;
i08u weight_m;
} status;
flt4 *ph2pi;
flt4 *weight;
flt4 *gamma;
flt4 *phase;
i08u *flags;
i08u *neigh;
i32s neighOfst[8];
i32s r,c;
i32s x0,y0,xSz,ySz;
flt8 unwTime;
flt4 binCut;
};

Please Could someone help me suggesting how I pass this dat
a type to call library function?
0 Kudos
Message 1 of 10
(3,290 Views)
A LabVIEW cluster is represented as a structure when it is passed to a DLL. You could create a cluster with all the data types in the correct order and then pass it to the DLL using the "Adapt to Type" data type. The problem is that LabVIEW will pass the data as a pointer to the structure, which is not always applicable for an existing dll. If you are using LabVIEW 6, you can have it create a template c file so that you can see how the data is represented. Usually, with very complex data types, using a wrapper function is preferred. In other words, you can create a function designed to pass values to and from LabVIEW, package them in whatever fashion is necessary, and call the desired dll function. This will be much easier with a structure which combines va
lues and pointers to values.
Message 2 of 10
(3,289 Views)
yes, i have a similar sort of problem. If you have derived the solution to your problem, I will appreciate if you can help me with this one.
The function I am using from the DLL requires a pointer to this structure passed to it.
typedef pAIListType
{
int device;
int unit;
int channel;
int gain;
int range;
int differential;
} pAIListType;

The function prototype is like this:
int pascal far pAIConfigureList (pAIListType far *list);

Note that paramater list is an array of type pAIListType.
How do I pass this paramater from labview? Do I use a cluster array? How do I make a wrapper function in labview?
I am very new to labivew, so I'll appreciate any feedback. Cheers,
Setu.
0 Kudos
Message 3 of 10
(3,289 Views)
> The function I am using from the DLL requires a pointer to this
> structure passed to it.
> typedef pAIListType
> {
> int device;
> int unit;
> int channel;
> int gain;
> int range;
> int differential;
> } pAIListType;
>
> The function prototype is like this:
> int pascal far pAIConfigureList (pAIListType far *list);
>
> Note that paramater list is an array of type pAIListType.
> How do I pass this paramater from labview? Do I use a cluster array?
> How do I make a wrapper function in labview?


Make a cluster of six int32s and build an array large enough for the
data to be written into by the DLL. You will probably want to use
Initialize Array for this. In the DLL node use the adapt to type option

and pass by pointer. This is what I would try, but there are several
assumptions being made here.

This is one of those points where you have to know more than what the
prototype tells you. The pointer going into the function could be only
an input for the DLL to look at but not change. It could be an
input/output where the DLL will look at and maybe change it. It could
be just an output where the value of the input doesn't matter.
Additionally, regarding allocation, the DLL could be assuming that the
memory is already allocated, or it could be allocating its own memory
and returning the pointer to it. These are the sorts of things that
have to be in the documentation because it isn't clear from the prototype.

My solution above assumes that the caller must preallocate and the DLL
will possibly inspect the data and will return values in the array.

Greg McKaskle
0 Kudos
Message 4 of 10
(3,289 Views)
Hi Greg,
Thanks for your reply. The function pAIConfigureList only reads the structure array, it does not modify it. Now the cluster array (which I want to pass to as a structure array) is already intialized prior to the function call. The cluster array however is variable size depending on user input, which is why it is required to be passed as pointer to first structure.

Now I have tried passing this cluster array to the function, but it does not work. Yes I used adapt type option and pass by pointer, but no luck. Any thoughts?

I appreciate your help, thanks.
Setu.
0 Kudos
Message 5 of 10
(3,289 Views)
Hi Setu,

Here is a solution that I have been playing to return back an array of clusters

typedef struct
{
int32 dimSize;
uInt8 array[1];
} LVU8;

typedef LVU8 **LVU8Hdl;

typedef struct
{
U32 DeviceId;
U32 VendorId;
U32 BusNumber;
U32 SlotNumber;
LVU8Hdl SerialNumber;
} LVDEVICE_LOCATION;

typedef LVDEVICE_LOCATION **LVDEV_LOC_HANDLE;

typedef struct
{
int32 dimSize;
LVDEVICE_LOCATION cluster_array[1];
} LVDEV_LOC_ARRAY;

typedef LVDEV_LOC_ARRAY **LVDEV_LOC_ARRAY_HANDLE;

LVPLX_API void GetAllDevices(LVDEV_LOC_ARRAY_HANDLE cluster_array)
{
int i,j;
int numDevices = 3;

DSSetHandleSize(cluster_array, sizeof(int32)+3*(sizeof(LVDEV_LOC_ARRAY)+(sizeof(int32)+16*sizeof(L
VU8))));
(*cluster_array)->dimSize = 3;
(*((*cluster_array)->cluster_array[0]).SerialNumber)->dimSize =16;
(*((*cluster_array)->cluster_array[1]).SerialNumber)->dimSize =16;
(*((*cluster_array)->cluster_array[2]).SerialNumber)->dimSize =16;


for(i=0; i<3; i++)
{
((*cluster_array)->cluster_array[i]).BusNumber = i;
((*cluster_array)->cluster_array[i]).VendorId = i*5;

for(j=0;j<16;j++)
(*((*cluster_array)->cluster_array[i]).SerialNumber)->array[j] = (10*j)+i;
}

}

The code doesnt do much but returns back 3*cluster which the array in my cluster is sized for 16. The problem I've been having , was ensuring I have allocated enough memory to handle the complete structure. This works for me, now all I have to do is put the real code in which get my array of data from the instruments.

Hope it helps
Regards
Ray Farmer
Regards
Ray Farmer
0 Kudos
Message 6 of 10
(3,289 Views)
Hi Ray,
Thanks for your response. The code is good, but sadly I don't understand much of it! But I think the code returns a cluster array right? I am after something (a wrapper function, or a CIN that someone might have already written) that can convert labview cluster array to a C structure array and pass it as pointer. My DLL function only needs to be able to read from the array, it does not need to return it. Sadly the DLL function was provided as part of the instrument driver (intelligent instruments dasport PCI-2045P-24) does not have code supplied with it so I can't chagen it.
Thanks again for your kind help.
Regards,
Setu.
0 Kudos
Message 7 of 10
(3,289 Views)
> Thanks for your reply. The function pAIConfigureList only reads the
> structure array, it does not modify it. Now the cluster array (which
> I want to pass to as a structure array) is already intialized prior to
> the function call. The cluster array however is variable size
> depending on user input, which is why it is required to be passed as
> pointer to first structure.
>
> Now I have tried passing this cluster array to the function, but it
> does not work. Yes I used adapt type option and pass by pointer, but
> no luck. Any thoughts?
>


You need to describe what is not working. Does it crash? How? Where?
If the DLL is debuggable, then you can place a breakpoint in it and
examine what is being passed into
it.

If this doesn't help you figure it out, you should probably contact
technical support.

Greg McKaskle
0 Kudos
Message 8 of 10
(3,289 Views)
hi greg,
okay here is what happens when i pass the cluster array to the dll function.
The dll function produces an error code as its output. In this case it produces an error code of 150, which correspondes to "The specified device is invalid". In my previous comment you will see that the device (number) is passed part of the cluster array. If I just pass it a single cluster than I get error 160 which is "the unit number is invalid". Unit number is the second varaiable in the cluster.
So this is what happens. I also don't know what I need to debug the DLL as it was supplied as part of my instrument driver. So I am very much stuck.
I appreciate your help greg.
Regards,
Setu.
0 Kudos
Message 9 of 10
(3,289 Views)
> The dll function produces an error code as its output. In this case
> it produces an error code of 150, which correspondes to "The specified
> device is invalid". In my previous comment you will see that the
> device (number) is passed part of the cluster array. If I just pass
> it a single cluster than I get error 160 which is "the unit number is
> invalid". Unit number is the second varaiable in the cluster.
> So this is what happens. I also don't know what I need to debug the
> DLL as it was supplied as part of my instrument driver. So I am very
> much stuck.



You might want to make sure that the cluster items are in the correct
order and make sure that you are using values that work together an
d
make sense with the version of the instrument.

To check the cluster order, use the help window and the wiring tool
hovering over the signal. To change it, popup and set the cluster order.

Greg McKaskle
0 Kudos
Message 10 of 10
(3,289 Views)