Jump to content

DLL connection for pointer structure


Recommended Posts

I wrote a VI for a function called VivaGrabInit for DLL, but it always is clashed when I run with a memory error. Can anybody help where I'm wrong in the code?

Function frome a head file

#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);

Link to comment

QUOTE (empstar @ Jun 8 2009, 01:27 PM)

I wrote a VI for a function called VivaGrabInit for DLL, but it always is clashed when I run with a memory error. Can anybody help where I'm wrong in the code?

Function frome a head file

#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);

You should learn a bit about C datatypes and how the C compiler allocates them. The two arrays in your structure are fixed size and therefore are not added as pointers to the structure but instead inlined. This means the structure is as long as the two arrays put together into memory. Also a LabVIEW cluster with two arrays in it is not the same as a C structure with two array pointers in it since LabVIEW arrays are not C pointers but special LabVIEW data types. But this does not apply here anyhow. What you will want to do is create an array of bytes with the length of 1000 (width) * 1000 (height) * 2 (sizeof(UINT16)) + VIVAGRAB_FRAME_METADAT which according to my calculations would be all together 0x2000000. Then pass that as C array pointer to the function.

And now comes the intersting part to extract the info from the array. This will be an interesting exercise for you to do. :-)

Rolf Kalbermatter

Link to comment

QUOTE (rolfk @ Jun 8 2009, 03:07 PM)

This is a crosspost from http://forums.ni.com/ni/board/message?board.id=170&message.id=414839&jump=true#M414839' target="_blank">here. It is considered polite to mention crossposts.

You should learn a bit about C datatypes and how the C compiler allocates them. The two arrays in your structure are fixed size and therefore are not added as pointers to the structure but instead inlined. This means the structure is as long as the two arrays put together into memory. Also a LabVIEW cluster with two arrays in it is not the same as a C structure with two array pointers in it since LabVIEW arrays are not C pointers but special LabVIEW data types. But this does not apply here anyhow. What you will want to do is create an array of bytes with the length of 1000 (width) * 1000 (height) * 2 (sizeof(UINT16)) + VIVAGRAB_FRAME_METADAT which according to my calculations would be all together 0x2000000. Then pass that as C array pointer to the function.

And now comes the intersting part to extract the info from the array. This will be an interesting exercise for you to do. :-)

Rolf Kalbermatter

Dear Rolf,

Thank you for your reply. I created an array of byte with 0x200000 and passed it as C array pointer to the function. There is no clash, and the array seems to be initialized. You can check the labview code I upload.

As you mentioned, the extraction of data from the array is an issue. I tried to use MoveBlock of Labview, but it didn't work correctly because there is no output pointer to control although I can extract the data with the following C code.

pVIVAGRAB_VIDEO_FRAME_ARRAY FrameBuffers; //FrameBuffers will point to an array of type VIVAGRAB_VIDEO_FRAME and is filled in by VivaGrabInit().

UINT16 *ImagePtr;

retval = VivaGrabInit(10,&FrameBuffers);

ImagePtr=(UINT16*)FrameBuffers;

Would you guide me how to extract data information in Labview? Thank you in advance.

Link to comment

QUOTE (empstar @ Jun 9 2009, 10:20 AM)

Dear Rolf,

Thank you for your reply. I created an array of byte with 0x200000 and passed it as C array pointer to the function. There is no clash, and the array seems to be initialized. You can check the labview code I upload.

As you mentioned, the extraction of data from the array is an issue. I tried to use MoveBlock of Labview, but it didn't work correctly because there is no output pointer to control although I can extract the data with the following C code.

pVIVAGRAB_VIDEO_FRAME_ARRAY FrameBuffers; //FrameBuffers will point to an array of type VIVAGRAB_VIDEO_FRAME and is filled in by VivaGrabInit().

UINT16 *ImagePtr;

retval = VivaGrabInit(10,&FrameBuffers);

ImagePtr=(UINT16*)FrameBuffers;

Would you guide me how to extract data information in Labview? Thank you in advance.

Why use MoveBlock?? The data is there in the byte array already so no need to move that to someplace else. You just have to decode the array data correctly :-)

Basically you want to Typecast that array in an array of 16 bit unsigned integers pass it through an Swap Bytes function to correct the endianess correction the Typecast does and resize it to a two dimensional array of 1000 by 1000

Then you also grab the subset from offset 2000000 (not 0x2000000) in the original array to the end and get there the additional array. Not pretty and certainly destroying some performance with it, but the alternative is to write a DLL wrapper in C which separates out those data parts into more LabVIEW friendly data types.

Rolf Kalbermatter

Link to comment

QUOTE (rolfk @ Jun 9 2009, 12:13 PM)

Why use MoveBlock?? The data is there in the byte array already so no need to move that to someplace else. You just have to decode the array data correctly :-)

Basically you want to Typecast that array in an array of 16 bit unsigned integers pass it through an Swap Bytes function to correct the endianess correction the Typecast does and resize it to a two dimensional array of 1000 by 1000

Then you also grab the subset from offset 2000000 (not 0x2000000) in the original array to the end and get there the additional array. Not pretty and certainly destroying some performance with it, but the alternative is to write a DLL wrapper in C which separates out those data parts into more LabVIEW friendly data types.

Rolf Kalbermatter

Dear Rolf,

As you suggested, I created an byte array with 0x200000 long by Initialize Array Function (All Elements are 0), and passed it to Call library function node with following configuration parameters

Name: FrameBuffers

Type: Array

Data type: unsigned 8-bit Integer

Dimensions: 1

Array format: Array Data Pointer

When I checked the FrameBuffers as an unsigned 8-bit array, only first four elements have non-zero values and the rest are all zeros although I expected all elements have non-zero values.

Why the only first four elements have non-zero values? Would you suggest any way to correctly extract data in the byte array? Thank you for your comments.

Link to comment

QUOTE (empstar @ Jun 9 2009, 06:45 PM)

Dear Rolf,

As you suggested, I created an byte array with 0x200000 long by Initialize Array Function (All Elements are 0), and passed it to Call library function node with following configuration parameters

Name: FrameBuffers

Type: Array

Data type: unsigned 8-bit Integer

Dimensions: 1

Array format: Array Data Pointer

When I checked the FrameBuffers as an unsigned 8-bit array, only first four elements have non-zero values and the rest are all zeros although I expected all elements have non-zero values.

Why the only first four elements have non-zero values? Would you suggest any way to correctly extract data in the byte array? Thank you for your comments.

Sorry I'm not a magician and my crystal ball does currently not work ;) . Translation: I have no idea!

You could have not initiliased the camera correctly, your camera is defect, your driver not installed right, your computer flaky, the moon phase not in the right place, etc. etc. I can really not tell you more with the information I have.

Correction: Looking at the original function prototype I see the parameter is actually a pointer to a pointer to a pointer!!!!!!!!!!!!!!!!!!!!!!!!!!!

This can not be done in LabVIEW. A wrapper DLL written in C is the only solution here.

Rolf Kalbermatter

Link to comment

QUOTE (empstar @ Jun 9 2009, 07:45 PM)

Dear Rolf,

As you suggested, I created an byte array with 0x200000 long by Initialize Array Function (All Elements are 0), and passed it to Call library function node with following configuration parameters

Name: FrameBuffers

Type: Array

Data type: unsigned 8-bit Integer

Dimensions: 1

Array format: Array Data Pointer

When I checked the FrameBuffers as an unsigned 8-bit array, only first four elements have non-zero values and the rest are all zeros although I expected all elements have non-zero values.

Why the only first four elements have non-zero values? Would you suggest any way to correctly extract data in the byte array? Thank you for your comments.

The first four bytes might be a u32 or i32 indicating the array size? Besides that, what Rolf just said is likely the reason the rest of it is all zeros.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.