Jump to content
patufet_99

Data type matching when calling a DLL

Recommended Posts

To use a controller from LabVIEW I have to use some functions of a DLL.

For one of the functions, according to the header file .h there is a structure data with parameters of different types that I have to pass to the dll. Some of the parameres are BYTE (1 Byte)  and WORD (2 Bytes).

When compiling this kind of structure with Visual C++ and looking at it's size with "sizeof()" it seems to me that 4 Bytes variables have to start in a position multiple of 4. For example if there is a BYTE and then a DWORD, the 3 Bytes after the BYTE are ignored and the DWORD starts at Bytes 5 to 8.

When defining a LabVIEW cluster to match the DLL structure, will LabVIEW do the same? If in my cluster there is a U8 variable and then a U32, will anyway the U8 take 4 bytes?

 

Thank you.

Share this post


Link to post
Share on other sites
7 hours ago, patufet_99 said:

When defining a LabVIEW cluster to match the DLL structure, will LabVIEW do the same? If in my cluster there is a U8 variable and then a U32, will anyway the U8 take 4 bytes?

No. LabVIEW assumes packed data types so a U8 followed by a U32 will take 5 bytes of space, not 8 bytes.

If you control the .h file, you can use #pragma pack to pack your struct. If you don't control the .h file, you can insert dummy BYTEs into your cluster.

Share this post


Link to post
Share on other sites

Thanks for your reply.

I cannot change the DLL. I guess that I will have to insert dummy bytes on my LabVIEW structures to get the correct data.

Share this post


Link to post
Share on other sites
On 5/24/2018 at 3:58 PM, JKSH said:

No. LabVIEW assumes packed data types so a U8 followed by a U32 will take 5 bytes of space, not 8 bytes.

If you control the .h file, you can use #pragma pack to pack your struct. If you don't control the .h file, you can insert dummy BYTEs into your cluster.

Actually it's more compilicated than that!

On Windows 32-bit, (and Pharlap ETS)  LabVIEW indeed assumes byte packing (historical reasons, memory was scarce in 1990 and that is when the 32-bit architecture of LabVIEW was built) and you have to add the dummy element fillers to make the LabVIEW cluster match a default C aligned structure. On Windows 64-bit they changed the alignment of LabvIEW structures to be compatible to the default alignment of 8-byte most C compilers assume nowdays.

And yes while the default alignment is 8 byte this does not mean that all data elements are aligned to 8 byte, The alignment rule is that each data element is aligned to a multiple of the greater of its own size or the current alignment setting (usually the default alignment but can be changed with #pragma pack to something else temporarily when declaring a struct datatype). 

The good news is that if you pad the LabVIEW clusters that you pass to the API, it will work on both Windows versions, but might not on other platforms (Mac OS X, Linux and embedded cRIO systems). So if you do multiplatform development a wrapper DLL to fix these issues is still a good idea!

Edited by rolfk

Share this post


Link to post
Share on other sites
14 hours ago, rolfk said:

On Windows 32-bit, (and Pharlap ETS)  LabVIEW indeed assumes byte packing (historical reasons, memory was scarce in 1990 and that is when the 32-bit architecture of LabVIEW was built) and you have to add the dummy element fillers to make the LabVIEW cluster match a default C aligned structure. On Windows 64-bit they changed the alignment of LabvIEW structures to be compatible to the default alignment of 8-byte most C compilers assume nowdays.

I didn't know that.

Do you mean 64-bit Windows or 64-bit LabVIEW? How does 32-bit LabVIEW behave on 64-bit Windows?

Share this post


Link to post
Share on other sites

Thank you for your answers.

The behavior that I observed by taking the "sizeof" structures is exactly as you described:

Quote

The alignment rule is that each data element is aligned to a multiple of the greater of its own size or the current alignment setting

 

A structure like this one:

typedef struct tagINTERFACEPARAM
{
    WORD  wSendPortNo;
    DWORD dwTimeout;      
} INTERFACEPARAM, *LPINTERFACEPARAM;

left two empty bytes after the WORD.

While

typedef struct tagCONNECTPARAM {
	WORD	wSendPortNo;
	WORD	wRecvPortNo;
	DWORD	dwSize;
} CONNECTPARAM, *LPCONNECTPARAM;

while this one did not left any empty byte.

 

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.