LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Import DLL: @dummy control@

Solved!
Go to solution

Hi!

I'm automatically importing a DLL with Labview.

A function has an argument with the following data type:

 

typedef struct CHILLER_CONTROLLER_state_tag
{
	SYSTEMTIME		TimeStamp;
	unsigned char	ChillerState;
	double			ChillerWaterSetPoint;
	double			ChillerWaterTemperature;
	double			ChillerExhaustTemperature;
	double			ChillerFlow;
	double			ChillerPressure;
} CHILLER_CONTROLLER_state;

Labview translates the struct in the following cluster:

 

Immagine.png

 

Where do the dummy controls come from?

 

0 Kudos
Message 1 of 9
(4,929 Views)

This is a guess, but I notice there are 7 of these, and the previous Chiller State is a uchar, which occupies a Byte.  Sounds like the @dummy control@ might be byte-sized "place-holders" designed to keep things on 8-byte boundaries.

 

Bob Schor

 

P.S. -- does this DLL work with LabVIEW?  If so, then you can also view the dummy controls as "Magic" to make things work ...

Message 2 of 9
(4,907 Views)
Solution
Accepted by topic author MarcoMauri

LabVIEW on Windows 32 bit platforms "byte packs" data in clusters. That means it aligns the data on byte boundaries. Visual C and many other C compilers align data in a structure (the synonym to a LabVIEW cluster) to a configurable data size. The default data alignment is 8 byte, and data elements in a structure are aligned to the smaller of the default alignment or its own element size.

That means that your doubles are aligned to a multiple of 8 bytes since a double has a size of 8 bytes.

 

However!!!!!! A library developer is free to either add explicit #pragma pack() statements in the header file to cause a different default alignment (which the Import Library Wizard would then honor) or ... gasp ... specify a different default alignment in the project settings to his library (which the Import Library Wizard would not be possible to know about).

Luckily most C programmers wouldn't even know how to change the project default alignment settings, so if there are no #pragma pack() statements in the header declarations it is a pretty safe, albeit not a fully safe, assumption to use the default 8 bit alignment.

Rolf Kalbermatter
My Blog
Message 3 of 9
(4,901 Views)

Thanks for answering Rolf.

as an add on I've found this interesting link about "The Lost Art of C Structure Packing".

0 Kudos
Message 4 of 9
(4,878 Views)

Hello everyone,

 

Sorry to resurrect this 6 year old thread .

 

I am recently encountering similar situation , where i received a 64 bit SDK from our vendor and creating a LV wrapper over that .

 

Most functions work fine. Here is a specific one that isn't accepting my inputs , that has this structure 

 

Frabto_0-1673357202406.png

 

The typedef in c is 

 

 */

typedef struct

{

    /// The connection handle

    LS_Handle_t _in_deviceHandle;

    /// Exposure mode

    /// see @ref LS_SDK_ExposureMode_t

    LS_SDK_ExposureMode_t _in_exposureMode;

    /// Exposure time [s]

    /// The valid value range depends on the connected camera

    float _in_exposureTime;

    /// Averaging number

    /// <br>Valid value range: 1 to 100

    uint32_t _in_averageNumber;

    /// Acquisition mode

    /// see @ref LS_VTC2400D_AcquisitionMode_t

    LS_VTC2400D_AcquisitionMode_t _in_acquisitionMode;

    /// Wavelength [nm]

    /// The wavelength of the DUT

    double _in_wavelength;

    /// Index of used wavelength range

    /// Two ranges can have the same wavelength at the border

    /// If index is @ref LS_UNSET_INDEX range will select automatically

    int32_t _in_wavelengthRangeIdx;

    /// Trigger mode

    /// see @ref LS_SDK_TriggerMode_t

    LS_SDK_TriggerMode_t _in_triggerMode;

    /// Timeout for hardware trigger [s]

    /// <br>Valid value range: 5 to 60

    float _in_hardwareTriggerTimeOut;

    /// Control flag to define whether an over exposed mask is created based on

    /// raw camera data or not. Please consult @ref LS_SDK_ExposureMaskControl_t

    /// for details

    LS_SDK_ExposureMaskControl_t _in_overExposedMaskControl;

    /// A custom over exposed threshold. The value must be in the interval

    /// [0.0, 1.0]. It is the relative ADU value from 0 to maxADU.

    float _in_overExposedCustomThresholdValue;

    /// Control flag to define whether an under exposed mask is created based on

    /// raw camera data or not. Please consult @ref LS_SDK_ExposureMaskControl_t

    /// for details

    LS_SDK_ExposureMaskControl_t _in_underExposedMaskControl;

    /// A custom under exposed threshold. The value must be in the interval

    /// [0.0, 1.0]. It is the relative ADU value from 0 to maxADU.

    float _in_underExposedCustomThresholdValue;

} LS_VTC2400D_2dMeasurement_Parameter_t;

 

Able to pass the parameters 

 

_in_deviceHandle

_in_exposureMode

_in_exposureTime

_in_averageNumber

_in_acquisitionMode

 

Not able to set any parameter from  '_in_wavelength', 

 

in_wavelegth just sets to the DBL minimum value , irrespective of any value i send, 

 

Any  thoughts on different formats i can try 

 

Thank You 

 

 

 

 

0 Kudos
Message 5 of 9
(1,891 Views)

@Frabto wrote:

Hello everyone,

 

Sorry to resurrect this 6 year old thread .

 

I am recently encountering similar situation , where i received a 64 bit SDK from our vendor and creating a LV wrapper over that .

 

Most functions work fine. Here is a specific one that isn't accepting my inputs , that has this structure 

 

Frabto_0-1673357202406.png

 

The typedef in c is 

 

 */

typedef struct

{

    /// The connection handle

    LS_Handle_t _in_deviceHandle;

    /// Exposure mode

    /// see @ref LS_SDK_ExposureMode_t

    LS_SDK_ExposureMode_t _in_exposureMode;

    /// Exposure time [s]

    /// The valid value range depends on the connected camera

    float _in_exposureTime;

    /// Averaging number

    /// <br>Valid value range: 1 to 100

    uint32_t _in_averageNumber;

    /// Acquisition mode

    /// see @ref LS_VTC2400D_AcquisitionMode_t

    LS_VTC2400D_AcquisitionMode_t _in_acquisitionMode;

    /// Wavelength [nm]

    /// The wavelength of the DUT

    double _in_wavelength;

    /// Index of used wavelength range

    /// Two ranges can have the same wavelength at the border

    /// If index is @ref LS_UNSET_INDEX range will select automatically

    int32_t _in_wavelengthRangeIdx;

    /// Trigger mode

    /// see @ref LS_SDK_TriggerMode_t

    LS_SDK_TriggerMode_t _in_triggerMode;

    /// Timeout for hardware trigger [s]

    /// <br>Valid value range: 5 to 60

    float _in_hardwareTriggerTimeOut;

    /// Control flag to define whether an over exposed mask is created based on

    /// raw camera data or not. Please consult @ref LS_SDK_ExposureMaskControl_t

    /// for details

    LS_SDK_ExposureMaskControl_t _in_overExposedMaskControl;

    /// A custom over exposed threshold. The value must be in the interval

    /// [0.0, 1.0]. It is the relative ADU value from 0 to maxADU.

    float _in_overExposedCustomThresholdValue;

    /// Control flag to define whether an under exposed mask is created based on

    /// raw camera data or not. Please consult @ref LS_SDK_ExposureMaskControl_t

    /// for details

    LS_SDK_ExposureMaskControl_t _in_underExposedMaskControl;

    /// A custom under exposed threshold. The value must be in the interval

    /// [0.0, 1.0]. It is the relative ADU value from 0 to maxADU.

    float _in_underExposedCustomThresholdValue;

} LS_VTC2400D_2dMeasurement_Parameter_t;

 

Able to pass the parameters 

 

_in_deviceHandle

_in_exposureMode

_in_exposureTime

_in_averageNumber

_in_acquisitionMode

 I doubt that you get even that far. 

 

exposureTime is a float, that means a 32-bit floating point number. It is therefore aligned on a 4 byte boundery (in 64-bit LabVIEW). averageNumber is an int32 value and therefore also aligned on a 4 byte boundery. This means that there CAN't be any dummy byte between them, but it seems you have that. But we can of course not say anything here as you FORGOT to attach the control (and the header declarations for all those LS_(something) datatypes too.

 

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 9
(1,875 Views)

Hi Rolf,

     Thanks  a million for the quick reply .

 

I created that control with the 'import shared Library' wizard in LabVIEW and the dummy controls got added from it. . I am adding the missing details of the typedef and attaching the LabVIEW control and header files.

I removed the top 4 dummy controls .It doesn't run as expected. i have to try this again , when i get a chance at the Instrument

.Can you please suggest any changes that i can try . 

 

typedef int32_t LS_Handle_t;

/// Fixed exposure time - set by user.
/// The @ref LS_LTOPD_2dMeasurement_Parameter_t _in_minSignalLevel and _in_maxSignalLevel
/// will be ignored.
LS_SDK_Exposure_Fixed,

/// Auto exposure with default settings.
/// The @ref LS_LTOPD_2dMeasurement_Parameter_t _in_minSignalLevel and _in_maxSignalLevel
/// will be ignored.
LS_SDK_Exposure_Auto,

/// Auto exposure with user defined signal levels. This is only available for LumiTop 2700 and 4000.
/// The @ref LS_LTOPD_2dMeasurement_Parameter_t _in_minSignalLevel and _in_maxSignalLevel
/// are used to find the optimal exposure time.
LS_SDK_Exposure_Custom_Auto,

} LS_SDK_ExposureMode_t;

 

Acquisition Mode : 

 

 

typedef enum

{

    /// Radiant intensity measurement

    LS_VTC2400D_AcqMode_RadiantIntensity,

    /// Irradiance measurement

    LS_VTC2400D_AcqMode_Irradiance,

    /// Setup mode

    LS_VTC2400D_AcqMode_Setup,

} LS_VTC2400D_AcquisitionMode_t;

 

Trigger Mode

 

 

typedef enum {
/// software trigger
LS_SDK_TriggerMode_Software,

/// hardware trigger
LS_SDK_TriggerMode_Hardware

} LS_SDK_TriggerMode_t;

Maskcontrol:

 

typedef enum {

    /// The mask creation is disabled

    LS_SDK_ExposureMaskControl_Disabled = 0,

    /// The mask is created using the default threshold stored on the device

    LS_SDK_ExposureMaskControl_CameraDefault = 1,

    /// A custom threshold value is applied

    LS_SDK_ExposureMaskControl_Custom = 2,

} LS_SDK_ExposureMaskControl_t;

 

 

Thank You,

 

0 Kudos
Message 7 of 9
(1,827 Views)

Hi Ralf,

    So to update further  , i was mapping the data types for each variable type between the LV and the C and found that one of the variable of type unsigned , is configured by LV as U64 instead of U32 .Not sure if that is cause. Have to check it at machine tomorrow.

 

Frabto_0-1673449889820.png

Thanks,

0 Kudos
Message 8 of 9
(1,810 Views)

I have no idea where that U64 comes from. It is clearly an uint32_t in the header file and I simply can't believe that the Import Library Wizard would go so much into the mist on this.

 

Also I'm not quite sure why it would generate 4 dummy byte elements rather than a single 32-bit dummy element.

Rolf Kalbermatter
My Blog
0 Kudos
Message 9 of 9
(1,784 Views)