LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Pointers to pointers in a C++ DLL

Hello NI community,

 

I'm trying to interface labview with an FPGA card manufactured by 4DSP.  4DSP provides a C++ dll and header file (4fm.dll and 4fm.h) that define a series of functions that can be used to operate the card.  The functions I need are fairly basic, just Open, Read, and Write.  However, this is a little tricky due to the data structure, _4FM_DeviceContext, that is required by the dll functions.

 

Here is the manual's description of 4FM_OpenDevice:

 

"3.10 _4FM_OpenDevice

_4FM_error_t _4FM_CALL _4FM_OpenDevice (_4FM_DeviceContext * ctx, const char *type, int devno);

 

Parameters:

ctx: the device context to operate on.

type: the type name of the device to open.

devno: the device number to open for the device specified by type.

 

Remarks:

Gets a handle from the OS that can be used for communicating with the 4FM board. The

parameter devno refers to the board that we wish to obtain the handle for. The first board is

‘0’ and typically this is the board nearest the CPU. Pass ‘1’ in order to get the handle to the

second board and so forth."

 

 

This *ctx pointer is also required by _4FM_ReceiveData:

 

_4FM_error_t _4FM_CALL _4FM_ReceiveData(_4FM_DeviceContext *ctx, void *buffer, unsigned long count);

 

 

Here is the definition of _4FM_DeviceContext pointed to by *ctx:

   typedef struct tag_4FM_DeviceContext

{

     const _4FM_DeviceType *lpType;

     HANDLE hDev;

     int ddr_offset;

     enum _4FM_Target target; //either 0 or 1

     struct

     {

          unsigned short hi;           unsigned short lo;

     }fpga_a_rev;

} _4FM_DeviceContext;

 

As you can see, 4FM_OpenDevice calls for a pointer that points to a struct that contains other pointers and structs.  Is it safe to call this DLL function in Labview and use the resulting DeviceContext pointer, or once the DLL function call returns is it possible for the memory pointed to by ctx to be overwritten at any time?  Any help would be greatly appreciated.

0 Kudos
Message 1 of 5
(2,988 Views)

steve_0001 wrote:
Hello NI community, 

As you can see, 4FM_OpenDevice calls for a pointer that points to a struct that contains other pointers and structs.  Is it safe to call this DLL function in Labview and use the resulting DeviceContext pointer, or once the DLL function call returns is it possible for the memory pointed to by ctx to be overwritten at any time?  Any help would be greatly appreciated.


Actually it may not be necessary to go with pointers to pointers. Unless you really need to access any information in that device context from the LabVIEW diagram directly you could get away in simply definining that parameter as Pointer sized integer in all Call Library Nodes. This will result in a 64 Bit integer (on 32 Bit platforms its lower significant 32 bits will be used) that contains the pointer. If you only need to pass that pointer around that would be enough. Now there might be a problem since it seems the function to open that context does not really create it but expect the caller to pass a complete structure to it. That is unfortunate since they basically take the object oriented idea and only carry it out halfway through.

So if there is no function in that library that truely creates this structure for you (and another one to dispose of it) you may have to trick a little. You can use a Call Library Node to call into the OS to call a memory allocation function such as HeapAlloc() to create a memory block of the required size and pass that pointer to your open function. Then at the end call HeapFree() on that pointer.

 

If you truely need to access contents in that context structure from within a LabVIEW diagram I would strongly recommend to create a wrapper DLL that translates between the DLL and your LabVIEW Call Library Nodes to make everything more friendly.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 2 of 5
(2,959 Views)
Thanks!  Using HeapAlloc() from a Call Library Node is a great idea.  One question though: what about the device handle?  Since the handle is a void pointer, could the memory referenced by the handle become invalid at some point after the DLL call returns?
0 Kudos
Message 3 of 5
(2,933 Views)

A bit of clarification for the casual observer: the device handle and device context aren't the same, handle is actually a member of context.  I would just use another HeapAlloc(), but how much memory should be allocated for a handle?

Message Edited by steve_0001 on 04-28-2010 09:32 AM
0 Kudos
Message 4 of 5
(2,930 Views)

steve_0001 wrote:
Thanks!  Using HeapAlloc() from a Call Library Node is a great idea.  One question though: what about the device handle?  Since the handle is a void pointer, could the memory referenced by the handle become invalid at some point after the DLL call returns?

Not knowing what a handle it is, when it is created/opened and what the DLL functions might or might not do with it, I have to pass on this question. If it is a Windows device handle created with CreateFile() then it will stay available until:

 

- Someone, somewhere calls CloseHandle on it.

- If it is a PnP device driver that is referenced it may also get invalidated when the PnP hardware is removed

 

Though accessing such a closed handle should simply return an according system error code.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 5 of 5
(2,926 Views)