LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Strange corruption of data when passing to DLL

Solved!
Go to solution

I'm working on an application that needs to communicate with a set of instrument drivers in a DLL.  Mostly it is working fine, and I can transfer data back and forth between LabVIEW and the DLL with no problems except for one incredibly frustrating bug.  I have created a scaled-down test DLL, with only the 'Set' and 'Get' functions and one other function to print a report of the values inside the DLL.  That library (with source code) and a set of VIs similar to those I'm using in the main application are attached.  

 

The parameters for the device are stored in the DLL in a series of C structures, for which I have made corresponding clusters in LabVIEW.  By using the 'MoveBlock' function to pass the data to and from the DLL by reference most of the clusters/structures transfer perfectly.  One even contains strings (char arrays in c) which are complicated to deal with, but it works fine.  

 

Unfortunately, there is one cluster ('General Settings' in the attached VIs) which contains a set of 13 numeric elements, mostly integer type, with two doubles at the end ('Acq. delay' and 'Hold After').  All the integer types transfer correctly to the DLL, but the doubles are corrupted, usually showing up as some gibberish like #.####e-315. When using the Visual Studio debugger and setting breakpoints to check values inside the DLL, they usually show up as denormalized (#DEN).  The corrupt values change when the LabVIEW inputs are changed - sometimes even both values in the DLL change when only one input is adjusted.  Furthermore, when the data is passed back to LabVIEW the correct values are recovered, so it seems the binary representation must be preserved in the transfer even though it is somehow misinterpreted in the DLL.  Even more puzzling is that another cluster in the application ('Presets') also contains both integer and double types, and those values are all transferred correctly to the DLL, so it doesn't seem to be something special about doubles.  

 

I've tested this on two different computers (both Win7, one 32bit and one 64bit) and see the exact same thing - even the corrupted values are the same. If anyone has experience with anything like this or can offer some suggestions I will be very grateful, since I'm pulling my hair out over this.  I'm sorry the attached VIs are so complicated - I wanted to keep as much of the structure as possible from the real application.  The main VI 'TestLIB_SetAndGet.vi' sets all the values to the DLL, writes a text file with some of them from within the DLL, and then copies the data back to LabVIEW.  As mentioned above, the relevant parameters are 'Acq. delay' and 'Hold after' in the cluster 'General Settings.' Their values show up in the report on lines 4-5.  Also note that the doubles 'Event Preset' and 'Time preset' from the 'Presets' cluster get transferred properly, showing up on lines 17 and 16 of the report.

 

Thanks in advance for any suggestions!

0 Kudos
Message 1 of 7
(2,483 Views)

Sorry, I forgot to mention that I'm running LabVIEW 2010 and that the DLL was compiled with Visual C++ 2010 Express. 

0 Kudos
Message 2 of 7
(2,482 Views)
Solution
Accepted by lee.bassett

Looks like alignment trouble.

 

Read this KB Article: http://zone.ni.com/reference/en-XX/help/371361H-01/lvconcepts/how_labview_stores_data_in_memory/ (especially section about clusters)

Try to add #pragma pack(1) before struct declarations

 

Andrey.


0 Kudos
Message 3 of 7
(2,470 Views)

Hi Andrey,

 

You were right, and #pragma pack(1) solved it.  I guess I was just lucky with the alignment on all the other structures.

 

Thanks for your help!

 

-Lee

0 Kudos
Message 4 of 7
(2,457 Views)

Hello I have a similar problem : I have to pass a cluster parameter containing numeric values in C DLL (that configure serial channels on a Serial Board) as a Struct so defined :

 

struct ChannelInfoEx

{

ViInt16 interfaceType;

ViInt32 baudRate;

ViInt16 numBits;

ViInt16 stopBits;

ViInt16 parity;

ViUInt16 flowControl;

};

 

This parameter is passed to a VI as a AdaptToType with a format Handles by Value

 

All the fields of the struct (except interfacetype the first one) have a shifted values (stopbits has the value for parity numbits for stopbits and so on).

This problem is raised when I have deleted from the first filed of the struct (ViInt16 channelName) and I have tried to define all the fields as ViInt32 and the parameters are passed correctly.

Someone could help me and explain this strange behaviour ?? It's a Labview bug ??

There is a way to avoid to redefine all the fields as ViInt32 in the DLL ??

 

0 Kudos
Message 5 of 7
(2,312 Views)

@sergin67 wrote:

 

Someone could help me and explain this strange behaviour ?? It's a Labview bug ??

There is a way to avoid to redefine all the fields as ViInt32 in the DLL ??

 


Yes, sure, there is a way. Please read the following kb:

Clusters in LabVIEW Do Not Line Up With Structures in Visual C++

0 Kudos
Message 6 of 7
(2,306 Views)

Ok thank you I read the article and I answer if the problem is solved.By By

0 Kudos
Message 7 of 7
(2,299 Views)