09-05-2016 09:19 AM
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:
Where do the dummy controls come from?
Solved! Go to Solution.
09-05-2016 10:50 AM - edited 09-05-2016 10:52 AM
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 ...
09-05-2016 11:01 AM
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.
09-06-2016 01:11 AM
Thanks for answering Rolf.
as an add on I've found this interesting link about "The Lost Art of C Structure Packing".
01-10-2023 08:58 AM
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
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
01-10-2023 10:29 AM
@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
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.
01-11-2023 07:16 AM - edited 01-11-2023 07:19 AM
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,
01-11-2023 09:12 AM
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.
Thanks,
01-11-2023 05:04 PM
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.