LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to create a structure pointer DLL using Call Library Function Node

I would like to control the pointer of a user defined structure with call Library function. I wrote a VI for VivaGrabInit, but it always is clashed when I run with a memory error. I desperately need someone's help for right coding. Thank you ahead.

 Function

#define VIVAGRAB_FRAME_BUFFER_SIZE     0x200000 //2Mb

#define VIVAGRAB_FRAME_WIDTH  1000

#define VIVAGRAB_FRAME_HEIGHT 1000

#define VIVAGRAB_FRAME_SIZE   (VIVAGRAB_FRAME_WIDTH*VIVAGRAB_FRAME_HEIGHT*sizeof(UINT16))

#define VIVAGRAB_FRAME_METADATA  (VIVAGRAB_FRAME_BUFFER_SIZE-VIVAGRAB_FRAME_SIZE)

 

typedef struct

{

   UINT16   FrameData[VIVAGRAB_FRAME_HEIGHT][VIVAGRAB_FRAME_WIDTH];

   UINT8    Metadata[VIVAGRAB_FRAME_METADATA];

} VIVAGRAB_VIDEO_FRAME, *pVIVAGRAB_VIDEO_FRAME, **pVIVAGRAB_VIDEO_FRAME_ARRAY;

 

extern "C" __declspec(dllexport) UINT32 VivaGrabInit(UINT32 NumFrameBuffers, pVIVAGRAB_VIDEO_FRAME_ARRAY *FrameBuffers);

0 Kudos
Message 1 of 5
(4,452 Views)

A pointer is just a pointer to a memory location.  To do this make a cluster (struct in c) with a 2-d U16 array preallocated to [VIVAGRAB_FRAME_HEIGHT][VIVAGRAB_FRAME_WIDTH] and a 1-d U8 Array preallocated to [VIVAGRAB_FRAME_METADATA];

 

Pass this to the pointer input of the dll.  This should pass the memory location of the pre-allocated (the arrays must have the correct size and type so that memory requirements are correct or you can crash youe application) cluster.

 

I think this is how I did this in the past, but I havent used a pointer to a structure in several months.

 

Paul Falkenstein
Coleman Technologies Inc.
CLA, CPI, AIA-Vision
Labview 4.0- 2013, RT, Vision, FPGA
0 Kudos
Message 2 of 5
(4,438 Views)

falkpl wrote:

A pointer is just a pointer to a memory location.  To do this make a cluster (struct in c) with a 2-d U16 array preallocated to [VIVAGRAB_FRAME_HEIGHT][VIVAGRAB_FRAME_WIDTH] and a 1-d U8 Array preallocated to [VIVAGRAB_FRAME_METADATA];

 

Pass this to the pointer input of the dll.  This should pass the memory location of the pre-allocated (the arrays must have the correct size and type so that memory requirements are correct or you can crash youe application) cluster.

 

I think this is how I did this in the past, but I havent used a pointer to a structure in several months.

 


The OP is a crosspost from here. It is considered polite to mention crossposts in a post!

 

I have to disagree here. First a LabVIEW array in a cluster is not the same as a C array pointer in a structure. One is a LabVIEW handle allocated using the LabVIEW memory manager and really a pointer to a pointer to a data structure that has also the dimension size(s) prepended and the other is just a C pointer.

 

Second, the two arrays in the C code are fixed size and hence get inlined into the structure. This results in a single memory block of the size  VIVAGRAB_FRAME_HEIGHT * VIVAGRAB_FRAME_WIDTH * sizeof(UINT16) + VIVAGRAB_FRAME_METADATA * sizof(UINT8).

 

So the OP will have to pass a simple LabVIEW byte array as C array pointer instead and then get into the fun of extracting the data correctly from this after the function call.

 

Rolf Kalbermatter

Message Edited by rolfk on 06-09-2009 10:11 AM
Rolf Kalbermatter
My Blog
0 Kudos
Message 3 of 5
(4,418 Views)

Sorry I havent passed a struct to a dll in a while.  Now that I look as my old code I have a struct as a preallocated Byte array.  I then did simple pointer math to get the offsets of the struct fields (assuming fixed sized fields). There is also the import shared library tool if you have the header files but I have not tried this.  I remember it being mentioned at ni week that there was a feature for autowrapping dlls with this wizard.

Paul Falkenstein
Coleman Technologies Inc.
CLA, CPI, AIA-Vision
Labview 4.0- 2013, RT, Vision, FPGA
0 Kudos
Message 4 of 5
(4,389 Views)

falkpl wrote:

Sorry I havent passed a struct to a dll in a while.  Now that I look as my old code I have a struct as a preallocated Byte array.  I then did simple pointer math to get the offsets of the struct fields (assuming fixed sized fields). There is also the import shared library tool if you have the header files but I have not tried this.  I remember it being mentioned at ni week that there was a feature for autowrapping dlls with this wizard.


The library import wizard is a tool not a magic wand. It can ease import of fairly basic DLL interfaces (the part which is tedious mechanical work) but it can not solve complicated C datatypes and pointer constructs eventhough it does attempt to do some of that too. But C is such a loosely defined language in that respect that one can not possibly think of all possibilities in which pointers and C datatypes can be mixed up by programmers to the point that no automated tool is able to translate it into a fixed typed language like LabVIEW.

 

Add to that that LabVIEW has not really an internal concept of pointers and especially function pointers and the whole exercise to translate some complicated APIs is in vain. While function pointers are simply to difficult to really implement in LabVIEW directly you can trick with complicated data pointer constructs by using rather complicated techniques in the LabVIEW diagram.

 

Here the function wants to get passed or probably more likely will return in a pointer a pointer array of array pointers! Anyone still with me after this sentence? Whoever has trouble to understand the implications of this sentence I would suggest to move on and try another exercise. Smiley Happy

 

For those still following, the C prototype in the header file does not specify many aspects of this at all. This must be determined from the manual, the context of the API, other C sample code using that function, "Fingerspitzengefühl" (intuition), and last but not least trial and error (and crashing it will many times Smiley Wink ).

 

Things that are not clear here are how many array pointers will be returned? (The four bytes altered after return would indicate that this is currently 1 but that might change if you change some configuration parameters before the call for instance to aqcuire an entire sequence of images.)

Will the function allocate the pointer array to hold them (unlikely) or not? Will the function allocate the array pointers (likely) or not? If it allocates them which function to use to deallocate them after use? All in all enough to drive a C programmer crazy to implement a call to that function. Now try to do that from within LabVIEW with tricks like MoveBlock etc. etc. and the neatness of LabVIEW where you do not have to worry about memory allocations in general gets rather a curse than an advantage.

 

I would not even consider trying to call that function directly from LabVIEW. Instead I would write a wrapper DLL that does the whole translation between LabVIEW and and this DLL in a way that makes the call in LabVIEW easy to do and the translation performant to be executed. Image acquisition is an area where performance often is beneficial if not mandatory.

 

Rolf Kalbermatter

Message Edited by rolfk on 06-11-2009 08:37 AM
Rolf Kalbermatter
My Blog
0 Kudos
Message 5 of 5
(4,373 Views)