LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Passing struct to dll from LV2011

I have a C++ dll with the following function call and struct type.

 

HRESULT CalData(tag_DATA _t *pCalData);

 

typedef struct

{

   unsigned int nNumOfPoint;

   unsigned short nTemp[MAX_TEMP];

   short nChOffset[MAX_CH][MAX_TEMP];

   short nChSpan[MAX_CH][MAX_TEMP];

   unsigned char byteChShift[MAX_CH + 1];

} tag_DATA;

 

MAX_TEMP = 8;

MAX_CH=8;

 

I have to allocate memory before hand so that dll can populate the structure with the values.

 

How can I call this using "Call Library Function" in LV2011? I have tried several combination of calling type with "Adapt to Type" Type.

Any help is appreciated.

 

Thank you,

Hiren

Hiren Patel
0 Kudos
Message 1 of 8
(3,255 Views)

Try the attached (you'll need to link the cln with the dll).

LabVIEW doesn't have fixed sized arrays (outside of the fpga suff) so you need to use clusters instead (the array to cluster node can help with making those).

Depending on how the dll was compiled you may need to try the other calling convention.

 

Message 2 of 8
(3,251 Views)

Hi Matt,

 

Thank you for promp reply. I have tried your solution and it works fine.

 

Now I ran into the other structure where I have to pass the values down to the code. Here is what I have.

 

HRESULT CommitCalData(u8 NumberOfPoints, tagSampleData_t sampledata);

 

typedef struct

{

   short nLowAD [MAX_TEMPERATURES] [MAX_CHANNELS];

   short nHighAD [MAX_TEMPERATURES[MAX_CHANNELS]];

   float fLowRef[MAX_TEMPERATURES] [MAX_CHANNELS];

   float fHighRef [MAX_TEMPERATURES] [MAX_CHANNELS];

} tagLCx_SampleData_t;

MAX_CHANNELS= 7

MAX_TEMPERATURES=8

 

How can I  pass this to the dll? Do I have to use the same method for passing the values down?

 

Thank you,

Hiren

Hiren Patel
0 Kudos
Message 3 of 8
(3,234 Views)

@matt W wrote:

Try the attached (you'll need to link the cln with the dll).

LabVIEW doesn't have fixed sized arrays (outside of the fpga suff) so you need to use clusters instead (the array to cluster node can help with making those).

Depending on how the dll was compiled you may need to try the other calling convention.

 


Are you sure about this? It seems overcomplicated. I have a VI I am currently working with where I pass a cluster with arrays to the DLL with no problems. Is it possible the OP is using empty arrays in his cluster? It is possible to set the array size to something other than empty within the cluster. For instance, something like the following will still make it croak?

 

 

 

0 Kudos
Message 4 of 8
(3,225 Views)

Wow, I just re-read my above post...my thoughts are all out of order. Must be bed time. I also thought about it further and I should add, the dll I'm calling was one written in-house where the structures for the c code/dll call were generated from the CLFN(right click->create .c file...). So, this may be what is allowing the passing of the arrays without issues in my case. 

0 Kudos
Message 5 of 8
(3,215 Views)

@Hiren wrote:

Hi Matt,

 

Thank you for promp reply. I have tried your solution and it works fine.

 

Now I ran into the other structure where I have to pass the values down to the code. Here is what I have.

 

HRESULT CommitCalData(u8 NumberOfPoints, tagSampleData_t sampledata);

 

typedef struct

{

   short nLowAD [MAX_TEMPERATURES] [MAX_CHANNELS];

   short nHighAD [MAX_TEMPERATURES[MAX_CHANNELS]];

   float fLowRef[MAX_TEMPERATURES] [MAX_CHANNELS];

   float fHighRef [MAX_TEMPERATURES] [MAX_CHANNELS];

} tagLCx_SampleData_t;

MAX_CHANNELS= 7

MAX_TEMPERATURES=8

 

How can I  pass this to the dll? Do I have to use the same method for passing the values down?

 

Thank you,

Hiren


While these are two dimensional arrays they are just as with the previous example fixed size and therefor are passed inlined in the structure by the C compiler. Basically there are now MAX_TEMPERATURES * MAX_CHANNELS elements for each structure element. So create a cluster with 56 int16 followed by 56 * int16, then 56 * float32 and again 56 * float32.

 

And are you sure it says tagSampleData_t sampledata and not  tagSampleData_t *sampledata in the parameter list? Because the way you wrote it it would mean the structure is passed by value, which is a rather inefficient way to pass such a large structure. The programmer of this DLL was certainly not a profi if this is the case. Instead of using Adapt to Type for the parameter to pass the cluster directly you would basically have to create a Call Library Node which has probally about 4 * 56 parameters.

 

While this still works you can see that it is getting a bit unpractical already, for me this would be already the point to start a C compiler and write a wrapper DLL that makes the whole interface more LabVIEW friendly.

Rolf Kalbermatter
My Blog
Message 6 of 8
(3,201 Views)

As rolfk (who is by far the best CLN expert I know of) pointed out since that it's passed by value and not by pointer (and given your code is in Hungarian notation I doubt you mistyped it). You're probably better off writing a separate C dll to help connect LabVIEW and your DLL. You could pass the data to your dll by pointer (you can use a similiar method to your first question), then your dll would dereference that pointer while calling the original dll.You could also pass arrays to your dll, and have your dll build the struct to pass to the original dll. I'd personally go with the second method.

 

I didn't even release that a struct could be broken up into separate parameters, hopefully I'll remember that if I need it in the future.


@for(imstuck) wrote:

Wow, I just re-read my above post...my thoughts are all out of order. Must be bed time. I also thought about it further and I should add, the dll I'm calling was one written in-house where the structures for the c code/dll call were generated from the CLFN(right click->create .c file...). So, this may be what is allowing the passing of the arrays without issues in my case. 



It works because of the generated C file. A LabVIEW array is variable length and implemented as handle to labview managed memory, a C array is typically either fixed size, or a pointer to malloced data, confusioning the two would corrupt memory (and hopefully crash instead of something worse).

0 Kudos
Message 7 of 8
(3,193 Views)

I have tried to write the wrapper function in C. That was the first thing I tried. But the given dll has so many dependency that it does not allow me to compile my C code.

 

And yes the function on the dll side is looking for pass by value not reference.

 

Thank you,

Hiren

Hiren Patel
0 Kudos
Message 8 of 8
(3,169 Views)