LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to set Call Library Node to read pointer variable to struct inside a struct in dll?

Hello,

I'm working to use instrument whose driver is dll written in C++.

 

To use the call library node in LabVIEW, I first use the configured the dll function.

Untitled.png 

So, to accept the input pointer variable, I searched for the data type of ptrs and it looks as follows

Untitled1.png

In this case, in the structure data, there are pointers to another structure variable.

To accept the that structure, I designed the labview variable as follows. 

Untitled2.png

Although call function node is working, it does not give me a data what I expected.

In this case, is it correct to design the labview shown in upper picture?

 

Thank you.

0 Kudos
Message 1 of 6
(844 Views)

It would be helpful if you posted more details, documentation of the driver would be nice.

 

You don't get the expected data because the library expects the members of BI_TABLE_PTRS_TIA to be all pointers (and a trailing fixed array). (I think; the BIPTR.. macros read like it). LabVIEW will at best pass a pointer to the containing struct, but all its members are by-value. It isn't clear from your post who should allocate the memory.

 

I would strongly recommend to create a wrapper dll that offers a more LabVIEW-friendly interface.

0 Kudos
Message 2 of 6
(805 Views)

That's not gonna work like this. A pointer is a pointer and LabVIEW does not know pointers. You could fiddle with this by creating an integer that is 32-bit (when using 32-bit LabVIEW) and 64-bit (when using 64-bit LabVIEW) and and then use MoveBlock call to copy the data out of it. Bat that gets tedious VERY fast!

 

In addition, those BIPTRxxxx() declarations are most likely more than just an alias for the according scalar data type, so that is likely going to cause trouble too.

 

And it most likely won't stop with this function but there will be others with similar complex parameters. Basically rather than trying to play C compiler on the LabVIEW diagram yourself it would be almost certainly more efficient to let that do a real C compiler for you, and create a wrapper DLL that translates between this fairly complex API types and a more LabVIEW friendly version of it.

Rolf Kalbermatter
My Blog
0 Kudos
Message 3 of 6
(779 Views)

Thank you cordm,

 

Function is defined as follows.

 

BIDRV_API BILONG32 CALLING_CONV BiDrv_TableRead (BI_DISP_HANDLE DispHandle, BI_TABLE_DESC_TIA *Desc, BI_TABLE_PTRS_TIA *Ptrs);

 

We bring a parameter(specific number) "DispHandle" from the output of previous function.

As pointer to "Desc" and "Ptrs" is used and pointer variable has a structure, whose structure type is defined as follows, (BIINT32 is predefined data type correspond to signed integer 32, BIUINT32 is unsigned integer 32)

 

typedef struct BI_TABLE_DESC_TIA_TAG
{
BIINT32 DrvRev;
BIUINT32 MyHandle;
BIUINT32 RunID; 
BiDispFunc Func;

BIUINT32 Res17[4];
BI_REAL_TIME BaseTime; (BI_REAL_TIME is a structure)
BI_TABLE_COLUMN_LENGTHS_TIA ColumnLengths; (BI_TABLE_COLUMN_LENGTHS_TIA is a structure)
BI_STATISTICS TotalStats; (BI_STATISTICS is a structure)

BIINT32 ProcComplete; 
BIINT32 Reserved1;
BIINT32 Reserved2;
BIINT32 Reserved3;

double EnhFreqAvg;
double FirstBaToFirstTag;

BIUINT32 Res1[60];
}BI_TABLE_DESC_TIA;

 

typedef struct BI_TABLE_PTRS_TIA_TAG
{
BI_REAL_TIME *BaTime; 
BIPTRDOUBLE(MeasPt, pad2)
BIPTRDOUBLE(StTime, pad13)
BI_REAL_TIME *StTimeRt; (BI_REAL_TIME is a structure)

BIPTRINT64(StEvent, pad4)
BIPTRDOUBLE(SpTime, pad12)
BI_REAL_TIME *SpTimeRt; (BI_REAL_TIME is a structure)
BIPTRINT64(SpEvent, pad14) 

BIPTRDOUBLE(Mean, pad7)
BIPTRDOUBLE(Min, pad8)
BIPTRDOUBLE(Max, pad9)
BIPTRDOUBLE(StdDev, pad10)

BIPTRINT64(Count, pad11)
BI_RAW_DATA_SET_TIA *Raw; (BI_RAW_DATA_SET_TIA is a structure)

BIUINT32 Res1[14];
}BI_TABLE_PTRS_TIA;

 

As you can see, pointer variable like BaTime has a structure as follows.

 

typedef struct BI_REAL_TIME_TAG
{
//16 bytes total
BIINT64 Seconds;
double Fraction;
}BI_REAL_TIME;

 

So I wanted to know whether it is possible to use a pointer variable to structure, and (structured) pointer variable inside the structure.

 

If there is anything you need to know to understand the function, please let me know.

0 Kudos
Message 4 of 6
(769 Views)

For the first parameter, you might get away with inlining BaseTime and TotalStats into the parent struct. With the second parameter you cannot configure LabVIEW in a way that it passes the parameter in the expected way.

 

As rolf wrote, you will be better off letting a C compiler do the difficult parts for you.

 

If you insist on using LabVIEW, look at this post and its thread to get an idea what rolf means: https://lavag.org/topic/22822-pointer-to-labview-array-for-net-dll/?do=findComment&comment=144484

Basically create a lot of pointers, make a cluster out of those and after the function call copy the data out of the pointers. You have to know what BIPTRDOUBLE and BIPTRINT64 do before that, though.

 

0 Kudos
Message 5 of 6
(757 Views)

Dear cordm,

Thank you for your reply and sorry for my late reply.

 

The driver dll file is offered by manufacturer and they don't allow me to handle it.

So I'm trying to use LabVIEW to read data using function.(especially BI_TABLE_PTRS_TIA has

the pointers which has data I want.)

The only source I can take a look at is an old version source code (I attached the source code of that function).

 

BIPTRINT64(name, pad) BIINT64 * name;

BIPTRDOUBLE(name, pad) double * name;

 

BIPTRINT64 and BIPTRDOUBLE are the definition for pointer variables and BIINT64 is a

redefinition of signed integer64.

 

And could you please explain how can I make a pointer in the LabVIEW? I'm not used to the concept of the pointer in the LabVIEW because LabVIEW does not allow user to handle the memory.

 

Thank you

 

0 Kudos
Message 6 of 6
(707 Views)