From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Use 2D array as input and output to dll

Solved!
Go to solution

Hi, I have problem with 2D array used with call library funtion to get array from DLL.

 

uint16_t is defined as unsigned short, which is unsigned 16 bit in labwindows.

In both following codes origFrame.height is 1024, origFrame.width is 1280.

QCam_Err DLLEXPORT FrameGrab(void* handle, uint16_t frame2D[1024][1280]) {

uint16_t *p;
p = (uint16_t*)origFrame.pBuffer;
// Copy each pixel to the 2D array
for(int i=0; i<origFrame.height; i++){
for(int j=0; j<origFrame.width; j++){
frame2D[i][j] = *p++;
}
}
}

Because 2D array is passed to DLL as 1D array, I also tried 1D array below but get the same numerical results.

 

 

QCam_Err DLLEXPORT FrameGrab(void* handle, uint16_t *frame1D) {
uint16_t *p;
p = (uint16_t*)origFrame.pBuffer;
for(int i=0; i<(origFrame.height*origFrame.width); i++){
frame1D[i]=*p++;
}
}

 

 

These two methods gives me the same result numerically in terms of the numbers in the output array.  

 

Interesting things is that the output array does have the right dimension but the all the numbers in the array is about ~40, while my expected values in all the array is 60.  I know that because I'm using this to get pixel values from a camera and I know the pixel values.  Also I used the same code in LabwindowsCVI as a normal program built as exe.  Everything works fine and I get my expected values back.  So apparently I'm missing something here when I changed parameters to make it dll.

 

What did I do wrong?  Thank you very much for your help!

 

Best,

Charles

 

 

 

 

 

 

 

 

 

Download All
0 Kudos
Message 1 of 13
(3,402 Views)

There are several ways to specify the size of the array in your DLL -- you need to be sure that you pass the array size in the format that the DLL wants.

 

BS

0 Kudos
Message 2 of 13
(3,360 Views)

When you use the call library make sure you are using the C calling protocol and not getting an array of pointers to an array of int16s.

 

The other possibliity is that your frame buffer pointer is indeed passing values around 40 back to the  LV program.  Instead of passing the framebuffer, try passing some calculated values based on I and J such that you can check that you are getting the right value in the right place.

 

(i<<8 + J & 0xff) will give you the lower 8 bits of I and J stuffed into each element.

LabVIEW ChampionLabVIEW Channel Wires

0 Kudos
Message 3 of 13
(3,355 Views)

Could you please elaborate on this a bit more?  I initiated an array in vi, that's 1024 row by 1280 columns and initiated to be all zero, data representation unsigned 16.  Then in the dll, the parameter I use is 

unsigned short frame2D[1024][1280]

 

Thanks.  

0 Kudos
Message 4 of 13
(3,339 Views)

It does seem to be passing the right value to the right place,

I used:

for(int i=0, j=0; i<(origFrame.height*origFrame.width); i++)
{frame1D[i]=frame1D[i]+j;
j++;}

 

Then the 1D array in labview returns from 0 to 65535 since it's 16bit, then it starts from 0 again.  So this means the array is passed into dll and back into labview correctly.

 

But I know that my pBuffer doesn't have value ~40...  I know for sure it should be ~60 and I do get ~60 back every time when I run the same code in Labwindows as long as it's not made into dll but made into exe file...  

 

This is very confusing.

0 Kudos
Message 5 of 13
(3,335 Views)

Well, what datatype is origFrame.pBuffer???

 

Your line

 

p = (uint16_t*)origFrame.pBuffer;

 

seems to indicate that it is something else than an array of uint16_t or you would not need a typecast. So what is it?

 

You always should avoid typecasts whenever possible! They can introduce strange effects and if they aren't necessary they are simply confusing. 

Rolf Kalbermatter
My Blog
Message 6 of 13
(3,326 Views)

Then the 1D array in labview returns from 0 to 65535 since it's 16bit, then it starts from 0 again.  So this means the array is passed into dll and back into labview correctly.

 

But I know that my pBuffer doesn't have value ~40...  I know for sure it should be ~60 and I do get ~60 back every time when I run the same code in Labwindows as long as it's not made into dll but made into exe file...  


yes it is a bit confusing.  But if setting the array to a known value works as a dll then I suggest that your call to pbuffer is not returning the correct values when it is a dll vs an exe.  You have verified all the LV call and return functionality.  There may be a timing issue when calling pbuffer to get the pointer or some other linked files when getting the value of pbuffer.

LabVIEW ChampionLabVIEW Channel Wires

0 Kudos
Message 7 of 13
(3,318 Views)
Thanks Rolf,
So it's just a reminder for myself.  It is actually indeed uint16_t.
When I change my code to p=origFrame.pBuffer;
the exe file gives me the same expected result, ~60. 
@rolfk wrote:

Well, what datatype is origFrame.pBuffer???

 

Your line

 

p = (uint16_t*)origFrame.pBuffer;

 

seems to indicate that it is something else than an array of uint16_t or you would not need a typecast. So what is it?

 

You always should avoid typecasts whenever possible! They can introduce strange effects and if they aren't necessary they are simply confusing. 


 

0 Kudos
Message 8 of 13
(3,308 Views)

@rolfk wrote:

Well, what datatype is origFrame.pBuffer???

 

Your line

 

p = (uint16_t*)origFrame.pBuffer;

 

seems to indicate that it is something else than an array of uint16_t or you would not need a typecast. So what is it?

 

You always should avoid typecasts whenever possible! They can introduce strange effects and if they aren't necessary they are simply confusing. 


Rolf,

 

But even if it was another length int the code would step through the buffer wrong and you would get weird numbers not all values off by 20. If it was really a buffer of bytes and you stepped throught it as int16 then you would get 2 bytes in each value and step off the end of the array.

 

My guess is a timing issue.  He sets the exposure time but does not trigger an exposure or wait the 10 mS for the exposure.  For a CCD you need to let the buffer fill before reading it out.  I think the buffer does not have what he thinks it has in it.

 

I don't know the exact hardware, but there seems to be something missing in the program.

LabVIEW ChampionLabVIEW Channel Wires

Message 9 of 13
(3,302 Views)

Thank you for your help.  

But I'm sure it has nothing to do with exposure or trigger because 60 is the offset of the camera when there's no photon hitting the camera.  I verified it with other image capture software coming with the company and micro-manager, which is an open source image acquisition software that works with the camera.  That's why I'm confused because the same code in exe file gives me the right results.

 

 

Download All
0 Kudos
Message 10 of 13
(3,283 Views)