From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Read Values from a Complex Struct includes Array, indicated by Pointer

Solved!
Go to solution

Hello,

 

I'm using the external *.dll, I was able to import it's methods to LabVIEW, but I have problem with reading values returned by some of them.

I have method: 

LONG CL3IF_GetTrendData(LONG deviceId, DWORD index, DWORD requestDataCount, out DWORD *nextIndex, out DWORD  obtainedDataCount, out CL3IF_OUTNO *outTarget, out DWORD *measurementData);

 

measurementData (out)
This is a buffer for acquiring the measurement value information. It stores data in the following structure up to the amount specified in obtainedDataCount. Ensure that the size of the area is greater than or equal to the amount of data in this structure × requestDataCount.
{
CL3IF_ADD_INFO addInfo;
CL3IF_OUTMEASUREMENT_DATA outMeasurementData[measurement target OUT count];
}
addInfo
Additional information associated with the measurement value. The number of times triggers are issued from the start of measurement is assigned when encoder triggers are not being used. The pulse count when a trigger was issued is assigned when encoder triggers are being used.
typedef struct {
DWORD triggerCount; Trigger count
LONG pulseCount; Pulse count
} CL3IF_ADD_INFO;
outMeasurementData
typedef struct {
LONG measurementValue;
BYTE valueInfo;
BYTE judgeResult;
BYTE reserved[2];
} CL3IF_OUTMEASUREMENT_DATA;

 

So as an output of the method LONG CL3IF_GetTrendData I have a pointer to the measurementData, which consists of one type struct and one array of type structs.

I tried to read the values using the Moveblock, but to be honest I don't know how to combine the parameters of Moveblock to make it work.

Can I ask you for a tips?

 

P.S I tried to read a value'index' from Pointer  LONG CL3IF_GetTrendIndex(LONG deviceId, out DWORD *index) - and I can't make it right as well.

0 Kudos
Message 1 of 6
(2,458 Views)

Hey Adriana,

 

From my experience something this complicated, a pointer to a buffer of structs, will be nigh on impossible to get LabVIEW to read it properly from the DLL.  I'd recommend creating a wrapper DLL in C, or C+ that formats it into something more compatible with LabVIEW, like arrays, ints and strings.

 

There are two main approaches to this, I'll let you decide what's best for your application.

 

1) Make a DLL that directly reads and parses the information from CL3_IF.dll, wrapping each of the functions you want to use in LabVIEW friendly versions.

 

2) Make a DLL that runs in the background, give it start and stop functions, and have it regularly call the CL3_IF.dll in the background and fill up it's own buffer arrays.  Then have other functions that pass everything currently read to LabVIEW as arrays of ints or longs, and then empties the buffer.

 

I hope this helps, and good luck!

0 Kudos
Message 2 of 6
(2,429 Views)

I don't think you should need to do any manual pointer manipulation.

 

As far as I can tell, this data in the combined structures is simply flattened in memory. Trick is to provide enough data as an input. The "out" in "out DWORD *measurementData" is a bit misleading, as it's really an in\out. If it where  just an out, who would be responsible for the memory and it's deallocation?

 

So, Id start with inputting a pointer to a large array of U8's. Then simply check if the dll changes anything in that array. If so, try to match it with the structures. That should be fairly simple, usually it involves casting and\or byte\word swapping.

 

 

If you get the dll to return anything, you're halfway there.

0 Kudos
Message 3 of 6
(2,414 Views)

Thanks for your replies,

before I start to write C wrapper, I would like to try accomplish it in LabVIEW.

 

@wiebe@CARYA -

I don't exactly understand, what you mean - I made some trials, but all ended up with LabVIEW crash, or DLL Error.

Can you check my examples, and point me where I am making a mistake?

 

 

Download All
0 Kudos
Message 4 of 6
(2,389 Views)
Solution
Accepted by topic author Adriana_S

I haven’t been able to look at the zip file in the earlier post as I’m currently only on mobile and the description you posted doesn’t look like completely legit C source code declarations so this is mostly guess work. But a 100 byte buffer would seem almost certainly to small and by no means satisfies Wiebes description of a rather large buffer. Also the whole business with DsNewPtr() is most likely totally unneccessary. Instead you should completely modify the Import Library Wizard generated Vi to directly do the correct thing. 

 

This most likely simply consists of allocating a big enough array (a quick guess would be 8 + 8 * requestDataCount bytes) of bytes with Initialize Array and passing that directly to the DLL function. Then on return of the function parse out the data from that array! 

Rolf Kalbermatter
My Blog
0 Kudos
Message 5 of 6
(2,371 Views)

Hi rolfk,

 

I imported the DLL once more, and I changed the inputs/outputs of the problematic method as you suggested - and it worked!

I was able to parse bytes to the needed data -thank you very much! 

 

Regards,

Ada

0 Kudos
Message 6 of 6
(2,354 Views)