LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Structures returned from dll

I am trying to interface my application in LV 7.0 to some external hardware uing a USB comm port.  The vendor furnishes a dll for function interface.  I have successfully used several of the functions with the Call Library Function of LV to create a handle to the comm port, open it, flush the RX buffer and read back the port number and baud rate as tests.  However, when I try to read the data of interest that is in a structure, I have not been able to make anything work.  The type def for the structure is:

 

typedef struct sN2KMsg {
    u32 Timestamp;
    u32 PGN;
    u8    Priority;
    u8    SrcAddr;
    u8    DestAddr;
    u32    Length;
    u8    Data[N2K_MAXLEN_TP];

} sN2KMsg;

 

and the function prototype is:

 

int ACommsN2K_Read  (int Handle, sN2KMsg *msg) .

 

My attempts so far are in the simple attached vi. This is my first attempt to use the Call Library Function of LV and am relatively new to LV programming.  Hopefully my problem is something simple or stupid I have or haven't done.

 

Thanks in advance for any help.

 

Hootowl

0 Kudos
Message 1 of 8
(3,701 Views)

Try this...

 

 

 

 

Oops, sorry, LabVIEW 7.0 eh? I'll see what I can do...

Message Edited by Troy K on 05-05-2010 02:05 PM
Troy - CLD "If a hammer is the only tool you have, everything starts to look like a nail." ~ Maslow/Kaplan - Law of the instrument
0 Kudos
Message 2 of 8
(3,688 Views)
The method you used should work. However, I think the I16s should be I32s. Are you sure that for the DLL "int" is supposed to be only 16 bits? Also, are you sure about the calling convention being stdcall?
0 Kudos
Message 3 of 8
(3,681 Views)

I double checked and the functions use stdCall for the calling convention.  All the other functions work using the I16 data type for the handle and I tried I32 for the MSGerror with no change in result.

 

Hootowl

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

I've had no success in converting the vi I attached above down to LV7.0 (dont have early enough version installed).

 

I've had similar trouble with structures in dlls in the past. What I did was flatten the structures in the function prototype.

 

 

Here's an image of my suggested block diagram.

ActisenseIntf.PNG 

Here's my suggested function prototype:

int16_t ACommsN2K_Read(int16_t Handle, uint32_t TStamp, uint32_t PGN, uint8_t Priority, uint8_t SrcAddy, uint8_t DestAddy, uint32_t Length, uint8_t *Data);

Troy - CLD "If a hammer is the only tool you have, everything starts to look like a nail." ~ Maslow/Kaplan - Law of the instrument
0 Kudos
Message 5 of 8
(3,630 Views)

Troy K wrote:

I've had no success in converting the vi I attached above down to LV7.0 (dont have early enough version installed).

 

I've had similar trouble with structures in dlls in the past. What I did was flatten the structures in the function prototype.

 


That is not gonna work! The structure is passed as pointer so you have to pass a pointer to a structure. What you have done is when the structure is passed directly. Then the C compiler treats each individual element of the structure as a seperate function parameter. Additional problems there would be how the elements smaller than the native integer size are passed. Most likely they are passed as individual parameters but it is also possible that the C compiler would pack them.

 

I see two potential problems with the original posters code:

 

1) int under 32 bit Windows is 200% for sure an int32 and not an int16. The other functions might work but this one might not.

2) Byte alignement in the structure. You have "length" parameter on an alignment that is not a multiple of its size. That is possible if you use so called packed data structures (in C you use #pragma pack(1)) and LabVIEW always uses that. Microsoft C however uses by default an alignment value of 8 which indicates to the compiler to align every element to the smaller of the two: it's own element size or that alignment. It is likely that the programmer of your DLL has not changed that default alignment but you only can be sure of that if you read the documentation and/or the header file to see if there is such statement.

If there is no indication that the DLL uses packed structures you would need to add a dummy filler byte in front of the length element to make the length be aligned correctly.

 

Last but not least you should check what value N2K_MAXLEN_TP is and adjust the cluster size in the right click pop-up menu of the Array to Cluster node accordingly (and hope that it doesn't need to be more than 256, which is the limit the Array to Cluster node allows).

Message Edited by rolfk on 05-06-2010 09:31 AM
Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 8
(3,603 Views)

rolfk wrote:

 

That is not gonna work!


Yep, you're absolutely right. That's not gonna work, sorry for the bum steer.

I just checked over the workaround I wrote two years ago an it looks like I remembered it wrong.

 

I'm working on the assumption that you have your data sizes correct. 

 

You do need to flatten the cluster but it still needs to be a cluster.

For some reason LabVIEW cant (or couldn't at the time) properly adapt a cluster to a struct that contains an array.

 

If the array is a fixed size (which mine was and yours appears to be) you need to replace each array element with a numeric.

 

Like this...

 

ActisenseIntf2.PNG

 

Once again, sorry for the dodgy suggestion in my earlier post.

Troy - CLD "If a hammer is the only tool you have, everything starts to look like a nail." ~ Maslow/Kaplan - Law of the instrument
0 Kudos
Message 7 of 8
(3,580 Views)

Troy K wrote:

You do need to flatten the cluster but it still needs to be a cluster.

For some reason LabVIEW cant (or couldn't at the time) properly adapt a cluster to a struct that contains an array.

 

If the array is a fixed size (which mine was and yours appears to be) you need to replace each array element with a numeric.


You need to make a distinction between arrays in a cluster that are variable sized and arrays that are fixed size. In the first case C does use a pointer in the cluster and in the second case it is inlined (flattened) into the structure.

 

LabVIEW always does use a handle for an array (which a string is too). A handle is not a pointer but a pointer to a relocatable pointer. A simple pointer as used in C is not easily relocatable since any client still holding the value of the old pointer will usually point into nirvana after a pointer has been reallocated, since the system often throws away the old pointer and creates a new one. This would make many things dataflow almost mandates hard to implement, so that is why handles were used.

 

So if the array is fixed size and therefore inlined you can simply replace it in LabVIEW by a cluster of the same size. And embedding a cluster inside a cluster is fully valid so there is no need to build an entire cluster by hand, but simply create an array and translate it to the right size element cluster using the Array To Cluster Node. That saves a lot of wirework. The limitation is that the Array To Cluster node only allows to create clusters with up to 256 elements. So if you need more you have to start to trick a bit. If it is only 512 you could get away by adding 2 * a 256 elements clusters right behind each other. Personally I usually do such structures by treating everything as a single array of uInt8 or whatever integer size is useful, and packing the information into the array before the call and out of the array after.

 

Or I resort to writing a wrapper DLL right away to make everything clear and shiny. If the C structure contains array (and string) pointers, the wrapper DLL is anyhow the highly advised solution. You can trick even here even more on the LabVIEW diagram and get away without wrapper DLL in some cases too, but first the C compiler knowledge needed to do that is in fact at least as detailed as would be required to write a wrapper DLL and usually even more than that, and doing C compiler stuff in the LabVIEW diagram gets a real maintenance nightmare sooner than later.

Message Edited by rolfk on 05-07-2010 09:09 AM
Rolf Kalbermatter
My Blog
0 Kudos
Message 8 of 8
(3,561 Views)