LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

C structures/pointers with labview clusters

Hi, I'm trying to use a function from an existing .dll. The function takes a pointer to a C structure, and I'm trying to use a call library node with a cluster in LabVIEW 8.5.1 to use the function already in the .dll.

 

The function is: void_stdcall GetTempConfigSettings(void *objptr, DPP_CONFIG_SETTINGS * CfgSet, BOOLEAN CurrentUpdate)

 

parameters: objptr: pointer to the DPPAPI, CfgSet: configuration settings, CurrentUpdate: current settings update.

 

the DPP_CONFIG_SETTINGS structure is definted the header file to the .dll as:

 

 // @struct DPP_CONFIG_SETTINGS | DPP Configuration Settings Storage Type
typedef struct _DPP_CONFIG_SETTINGS {
    //MCA Properties
    byte AcqMode;            // @field acquisition mode 0=MCA,1=MCS
    byte MCSTimebase;        // @field MCS timebase value (0-15) see CAcqMode
    byte MCAChannels;        // @field number of channels 4=256,3=512,2=1024,1=2048,0=4096,5=8192
    byte BufferSelect;        // @field Holds Buffer Sel A&B,Buffer Sel Hardware,see DPPBufferSelect
    byte TTLGate;            // @field gate input settings, determines events included/excluded from spectrum, see DPPGate
    byte SlowThreshold;        // @field Slow ch threshold, Events w/amp lower not added to spectrum
    long PresetTime;        // @field var holds preset time, used in usb
    long PresetCount;        // @field preset count in selected channels, ch are set in SCA8
    long SCA[8];            // @field SCA values, LL, UL, and Enable are stored together

    //Shaping Properties
    byte TimeToPeak;        // @field TimeToPeak register setting
    byte Decimation;        // @field decimation setting for pulse shaping
    byte FlatTop;            // @field flatop register setting
    byte PUREnable;            // @field pile-up rejection enabled
    byte FastThreshold;        // @field Fast Ch Threshold, events w/fch amp below this are rejected
    byte RTDSlow;            // @field Risetime Discrimination slow threshold
    byte RTDOn;                // @field Turns RTD on, and sets the amplitude and timing thresholds
    byte RTDFast;            // @field RTD Time Threshold,Events w/HWHM wider than this are rejected
    byte BLR;                // @field Baseline Restoration, see udBLR.Value notes for values
    byte BaselineOn;        // @field use autobaseline during detector reset

    //Gain PZ Properties
    byte CoarseGain;        // @field stores current coarse gain value
    long FineGain;            // @field stores current fine gain value
     long PoleZero;            // @field pole zero adjust value
    long InputOffset;        // @field input offset
    byte InputPolarity;        // @field use InvertEnable during detector reset
    byte DetReset;            // @field detector reset lockout period

    //Power Properties
    long TEC;                // @field TEC temperature setting (displayed in Kelvin)
    byte HVEnabled;            // @field high voltage setting enable
    long HV;                // @field high voltage setting value
    byte PreampPower;        // @field preamp power select value (5v or 8.5v)

    //Misc Properties
    byte AnalogOut;            // @field dac enabled and DAC output type,(stobed peak,shaped pulse,dec inp,fast ch)
    byte OutputOffset;        // @field Output DAC offset, -64…+63,(signed)(D7-D1) (-500mV to +492mV)
    byte AuxOut;            // @field Aux output type
    byte AudibleCounter;    // @field audio volume setting
} DPP_CONFIG_SETTINGS, *LP_DPP_CONFIG_SETTINGS;

 

I've tried defining a cluster with a long array for SCA[8] and with just 8 longs in place of SCA[8]. I'm not really sure what to try; any help would be appreciated. Thanks!

0 Kudos
Message 1 of 8
(7,099 Views)
What did you use for "long"? If you're trying to create a humongous cluster, then for those elements that are arrays you should use Array to Cluster before putting them into the cluster. I.e.:
Message 2 of 8
(7,086 Views)

Hi,

 

You should clearly understand, how data stored in the memory.

 

Question for you:

You have structure like this:

 

typedef1.png

 

Can you say which value will return sizeof()? You may think - 46 bytes (6x1 + 2*4 + 8*4). Wrong! Right answer is 48, because between char b6 and long l1 you have two bytes gap for alignment.

Well, if DLL is your DLL, then you can add #pragma pack(1), then you will have no gap. But if your DLL is not yours, then you should add according gap in LabVIEW cluster:

 

struct.png

Also take a note, that arrays stored in structures indirectly, as result cluster with array will not work for you. But LabVIEW stores clusters embedded within other clusters directly in line and with no indirection, so you can replace your array with cluster with appropriate number of the elements as shown in post above.

 

Hope it helps,

 

Andrey.

 

Message Edited by Andrey Dmitriev on 07-29-2009 09:09 PM
Message Edited by Andrey Dmitriev on 07-29-2009 09:15 PM
Message 3 of 8
(7,080 Views)
Thanks for your help. But I think I figured out a way to do it: I wrote a wrapper dll creating the struct and giving a pointer to it, I [think I] can use this pointer (which is returned as a numeric) as in input into the GetTempConfigSettings function in the original dll.
0 Kudos
Message 4 of 8
(7,054 Views)

Andrey Dmitriev,

     Here I have a doubt.  What if the structure you shown has enum instead of char?  As I learned in other forums that, compiler allocates memory for an enum datatype (it could be 1byte or 2bytes or 4bytes) based on someother thing, how can we predict the number of gaps we need to add for a cluster (which equivalent to that C structure)?

 

-Ajay.

--
Ajay MV


0 Kudos
Message 5 of 8
(6,294 Views)

with enum - in general same as with numeric.

 

What you can do for understanding how LabVIEW stores data in memory is pretty simple and straight forward test - use MoveBlock function for transferring data from cluster into byte array:

 

MoveBlock.png

 

now you can see that U16 enum takes two bytes as expected.

 

Be careful - if your cluster is "shorter" than the destination, the you will read memory outside of cluster - therefore exception may occur.

 

Andrey.

0 Kudos
Message 6 of 8
(6,281 Views)

Andrey Dmitriev,

 

     That's cool.  But now I want to reference a structure as follows, 

struct XXX

{

     int AAA;

     char BBB[10];

    float CCC[40];

     float DDD[40];

     int32 EEE;

     int32 FFF;

}

 

DLL Header:
 

ER_CODE KMAPI CLSetRankData(DEVICE_HANDLE hDevice, int32_km DataNo, const CL_RANK_DATA* RankData); 

where the typedef of CL_RANK_DATA is as follows,

typedef struct tCL_RANK_DATA
{
	CL_RANK_TYPE	        Type;							
	int8_km			RankName[CL_RANK_NAMESIZE_SAVE];
	CL_xyDATA		        xyPoint[CL_RANK_POINTNUM];		
	CL_TcpduvDATA	        TcpduvPoint[CL_RANK_POINTNUM];	
	int32_km		        PointNum;						
	int32_km		        Enable;							
}
CL_RANK_DATA;

You can find that I have int8_km in the typedef is a string.  How can I construct a LabVIEW cluster which defines this structure?  Also notice that I need to pass the pointer of the cluster to the method.

 

Kindly let me know how to handle this in LabVIEW.

 

Thanks,

Ajay

--
Ajay MV


0 Kudos
Message 7 of 8
(6,252 Views)

@Ajayvignesh MV wrote:

Andrey Dmitriev,

 

     That's cool.  But now I want to reference a structure as follows, 

You can find that I have int8_km in the typedef is a string.  How can I construct a LabVIEW cluster which defines this structure?  Also notice that I need to pass the pointer of the cluster to the method.

 

Kindly let me know how to handle this in LabVIEW.

 

Thanks,

Ajay


 Let's keep the discussion in one place. You've already posted your own thread, so instead of continuing to hijack this thread, keep all responses in your own thread.

0 Kudos
Message 8 of 8
(6,239 Views)