LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

read void pointer from dll

Solved!
Go to solution

I have a dll function which I have written into a call library function node.

it is structured like so:

int DataGetLatest(unisgned int *puFrameNumber,

                           unisgned int *puElements,

                           unisgned int *puFlags,

                           void *pDataDest)

 

pDataDest is defined as a structure like so:

 

typedef struct PositionStruct

{

float x;

float y;

float z;

}Position 

 

I want to get at the data in pDataDest and manipulate it. 

I've seen postings about int data that tell you do add another call to this function:

 

Then create a new Call Library Node and fill in folowing:

Library Name: LabVIEW
Function Name: MoveBlock
Calling Convention: cdecl
Execute in UI Thread

Return Value: void
1. Parameter: Name: source; Type: uInt32 passed by Value
2. Parameter: Name: dest; Type: int32 passed as Pointer
3. Parameter: Name: len; Type: int32 passed by Value

 

How do I get at structured data?

 

 

 

 

0 Kudos
Message 1 of 8
(3,680 Views)

I never had any luck bringing in structures or typedefs like that.  My suggestion would be to revise the DLL so it can put out three arrays (x,y,z).  If you use the DLL with some other software, add a function (such as DataGetLatest_Flat) to the DLL.

 

Sorry I can't be more encouraging.

-Matt Bradley

************ kudos always appreciated, but only when deserved **************************




0 Kudos
Message 2 of 8
(3,670 Views)

You don't.

 

You can however use the array of U8 type to retrieve this kind of data and cast it to a cluster.

 

See picture.

The upper screenshot shows the configuration of the DLL parameter.

The middle one shows the complete example.

The bottom one shows an example that can be used to find the correct size and byte ordering.

 

Data is stored in memory as bytes. The pointer points to the first byte. By retrieving enough bytes from the pointer position onwards you get all bytes related to your structure. After that you will have to map the bytes to the individual structure elements.

 

Message Edited by andre.buurman@carya on 06-11-2009 09:39 AM
Message Edited by andre.buurman@carya on 06-11-2009 09:42 AM
Regards,
André (CLA, CLED)
Message 3 of 8
(3,657 Views)

It is not entirely clear how the void* data pointer should be interpreted. If it is really just a pointer to the structure as your post seems to indicate it is very trivial.

 

You just create a cluster with the three single precision values and configure the parameter to Adapt to Type and wire that cluster to that parameter.

 

If it is however an array of clusters instead then things would get a little more complicated.

 

Rolf Kalbermatter

Rolf Kalbermatter
My Blog
Message 4 of 8
(3,652 Views)

I'll try the methods discussed above to solve my issue. 

 

To answer some questions:

1).  I can't directly modify the dll.  It has been provided by a vendor, but I need to write my program using it in Labview

 

2).  The cluster is actually a cluster array of that is puElements long.

 

3).  The 4 parameters in the function correspond to

puFrameNumber = # associated with the received data

puElements = # of markers in the frame of data

puFlags = current status of system

puDataDest = memory pointer to data

 

Thanks for any more help that can be provided.

0 Kudos
Message 5 of 8
(3,631 Views)

GuruDoo wrote:

I'll try the methods discussed above to solve my issue. 

 

2).  The cluster is actually a cluster array of that is puElements long.

 


Then you should create an array of float32 (single precision float, the C datatype double would be a LabVIEW double precision float) elements with 3 * puElements elements in it. Pass this as an array data pointer to your DLL function.

 

On return you will have in index 0 the array[0].x element, index 1 the array[0].y element, and index 2 the array[0].z element, and then the three elements for the second cluster record and so on.

 

Rolf Kalbermatter

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 8
(3,616 Views)

I've come across another complication.  I have gotten my program to work as long as the items in the structure are of uniform type (all floats, unit8, etc) like so:


 typedef struct PositionStruct

{

float x;

float y;

float z;

}Position

 

Any hints or tricks when the items in the structure are not uniform (floats and chars etc) or embedded structures like so:

 

 

typedef struct SensorDataStruct

{

unsigned char ucPeak;

unsigned char ucDRC;

unsigned char ucCode;

unsigned char ucPeakNibble;

}SensorData

 

typedef struct FullRawDataStruct

{

float            fCentroid [NUM_SENSORS]

SensorData SensorData[NUM_SENSORS] 

}FullRawData

 

I'm having trouble getting cases like this to work.  Thanks for the help again.

 

 

 

 

0 Kudos
Message 7 of 8
(3,606 Views)
Solution
Accepted by topic author GuruDoo

GuruDoo wrote:

I've come across another complication.  I have gotten my program to work as long as the items in the structure are of uniform type (all floats, unit8, etc) like so:

 

 

Any hints or tricks when the items in the structure are not uniform (floats and chars etc) or embedded structures like so:

 

 

typedef struct SensorDataStruct

{

unsigned char ucPeak;

unsigned char ucDRC;

unsigned char ucCode;

unsigned char ucPeakNibble;

}SensorData

 

typedef struct FullRawDataStruct

{

float            fCentroid [NUM_SENSORS]

SensorData SensorData[NUM_SENSORS] 

}FullRawData

 

I'm having trouble getting cases like this to work.  Thanks for the help again.


Then you are in a bit more trouble. Basically you still can do a correctly sized flat array with the least denominator of all elements. Here you could choose two possibilities:

 

1) an array of 2 * elements float32's and then index the odd elements, typecast them to int32, pass through Swap Bytes and Swap Words and typecast to an array of (u)Int8 which will give you 4 single byte integers.

 

2) an array of 8 * elements (u)int8's then extract the 4 elements from 8 * n and typecast them to an int32, pass through Swap Bytes and Swap Words and typecast to a single precision number, and also extract the four elements from 8 * n + 4 and use them as your 4 char elements.

 

In LabVIEW > 8 you have another option to pass in an array of 8 * elements uInt32', pass it through a Byte Array To String function and then through a Unflatten from String with the correct Endianess for your platform selected and the "data includes array or string size? (T)" input set to false.

 

Don't pass directly a string of appropriate size to the function as a C string pointer if you want to get binary data back from the function. LabVIEW on return from the function will scan the string and terminate it at the very first NULL byte it encounters and only return that part since this is the standard C way for string buffer termination.

 

All this is quite some work and for other more complicated cluster arrays it may be even more work and fiddling so I would most times suggest to write a small wrapper DLL in C instead to do this more easily.

 

Above example could be as easy as:

 

typedef struct SensorDataStruct

{

unsigned char ucPeak;

unsigned char ucDRC;

unsigned char ucCode;

unsigned char ucPeakNibble;

}SensorData

 

typedef struct FullRawDataStruct

{

float            fCentroid [NUM_SENSORS]

SensorData SensorData[NUM_SENSORS] 

}FullRawData;

 

 

typedef struct LVFullRawDataStruct {

int32 size;

FullRawData data[1];

} LVFullRawData, **LVFullRawDataHandle;

 

int32 MyFunction(.... , FullRawData pData[], int32 numElm, ....);

 

int32 LVFunction(.... , LVFullRawDataHandle pData, ....)

{

    return MyFunction(.... , (*pData)->data, (*pData)->size, ....);

}

 

Since there is no alignment issue in this C structure, you can simply construct the cluster one to one from the C structure and pass it as an array of those elements to the LVFunction which will take apart the LabVIEW array handle and pass its elements as individual C datatypes to the actual C function.

 

C alignment issues can be handled by adding according dummy bytes (uInt8 elements) into the LabVIEW cluster since LabVIEW does always full byte packing.

 

Rolf Kalbermatter

Message Edited by rolfk on 06-12-2009 08:49 AM
Rolf Kalbermatter
My Blog
0 Kudos
Message 8 of 8
(3,596 Views)