LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How do I get the memory address of an array?

Solved!
Go to solution

Hi All

 

Please bear with me, as this can be confusing. Let me know if you have questions.

 

I have a Hamamatsu CCD  and an external DLL that came with it I'm using. I call the function "DcamCapture" - this sends the capture command to the CCD.

From its documentation: 

 

"BOOL DcamCapture(LPVOID pImageBuff, INT nBuffSize)

 

[Summary]
Starts to capture one image from the device.

 

[Arguments]
pImageBuff Specifies the starting address of the buffer where the image data is
to be stored.

 

nBuffSize Specifies the buffer size (number of bytes).

 

[Note]
(1) This function issues an instruction to start capturing the image. Since the image
capturing is not complete even when this function ends, use the DcamWait

function to check whether image capturing is complete."

 

The bold is my own. So, after I call this function, I must call DcamWait. The problem is, by this point, labview has already written the pImageBuff variable to its indicator - in fact, it writes it immediately after this function returns. But this is before the data has even been written to memory! So I get out exactly what I put in - an empty array. 

 

In C++, this is not a problem. What they do in their example code is call DcamCapture, loop DcamWait, then dereference the pImageBuff pointer after all this is done. 

 

I don't know how to dereference the array pointer in Labview. 

 

So I have to, as an awkward hack, call DcamCapture TWICE; first I call DcamCapture, then DcamWait, then DcamCapture again - this time, I'm using the CLF to dereference the pImageBuff pointer, which (now) has the correct data. 

 

So - How do I get the memory location of the pImageBuff? And then, how can I access it?

 

Thanks for your help. I've called NI and they are "thinking" about my problem - I'd like to see if anyone here can arive at a solution.

0 Kudos
Message 1 of 16
(7,846 Views)

Attached is my workaround code, for illustration. 

0 Kudos
Message 2 of 16
(7,842 Views)

What's with all the local variables?

 

You can't "dereference" an array in LabVIEW because memory is not managed the same way as you would in a C/C++ program. LabVIEW performs its own memory management, and most of that is hidden from you, and in many ways this is actually a good thing. Having said that, what you are doing certainly will work. An alternative is to create a simple wrapper DLL that encompasses that, so you'd call just one function from your DLL, but I don't really see much gain in doing this, as you're adding another layer of DLL.

0 Kudos
Message 3 of 16
(7,828 Views)
Solution
Accepted by topic author pobrepablo1

You can do this using LabVIEW's memory manager functions, which you call by setting the library name to "LabVIEW" in the call library function node.  The functions you need are DSNewPtr, MoveBlock (which actually copies data), and DSDisposePtr.  There is brief documentation on these functions in the LabVIEW help.  You'll need to call DSNewPtr to allocate the memory, pass that to DCamCapture, loop on DCamWait, use MoveBlock to copy the data from that pointer into an array that LabVIEW manages, and finally deallocate the pointer.  Here's an example of a somewhat similar sequence: http://forums.ni.com/t5/LabVIEW/array-pointer-from-dll/m-p/1217453#M519958.

Message 4 of 16
(7,820 Views)

That's not really dereferencing an array - it's creating a new buffer in which data gets copied back and forth. I'm not sure why this would be easier than what the OP is already doing.

0 Kudos
Message 5 of 16
(7,817 Views)

@smercurio_fc wrote:

That's not really dereferencing an array - it's creating a new buffer in which data gets copied back and forth. I'm not sure why this would be easier than what the OP is already doing.


Yes; I edited my post so as not to be contradicting your correct information, sorry I wrote it that way initially.  I'm not sure my suggestion is easier, but it's closer to what the OP seemed to want (and to the described sample code in C).

0 Kudos
Message 6 of 16
(7,814 Views)

@smercurio_fc wrote:

That's not really dereferencing an array - it's creating a new buffer in which data gets copied back and forth. I'm not sure why this would be easier than what the OP is already doing.


What the OP is doing could be dangerous, if LabVIEW deallocates the array while the camera function is writing to that memory location.  I'd say it's good luck that the OP's approach works.  It sounds like the camera is holding on to a copy of the pointer after the function returns, and there's no guarantee that LabVIEW won't do something else with that memory once the call library function node completes.  Using DSNewPtr guarantees that LabVIEW won't rearrange memory while the camera is still using it.

0 Kudos
Message 7 of 16
(7,808 Views)

Hi guys, 

 

Manipulating memory is preferable to calling DcamCapture again - latency is important to our customers. Sometimes we'll be in "real time" mode where we loop DcamCapture for continuous data streaming. Busying the camera with a spurious command is something I'd like to avoid if possible. 

 

Thank you guys so much for your suggestions. I'll try implementing the pointer manipulation in a bit - lunch time now 😉

0 Kudos
Message 8 of 16
(7,802 Views)

@nathand wrote:

@smercurio_fc wrote:

That's not really dereferencing an array - it's creating a new buffer in which data gets copied back and forth. I'm not sure why this would be easier than what the OP is already doing.


What the OP is doing could be dangerous, if LabVIEW deallocates the array while the camera function is writing to that memory location. 


"If" LabVIEW deallocates the memory. That's the real question. I know 2 things: (1) An array is only guaranteed to be in place during a DLL call. (2) As long as you do nothing with a wire (like branching it), LabVIEW doesn't do anything about where that memory is located. So, which one wins out in this case? I can see your point in that given (1), the safe approach is to do what you say. But if (2) is true in this case, is it necessary? I honestly don't know if (2) is true here or not, since I don't know the bowels of the LabVIEW compiler (pick your LabVIEW version). I'm asking here for my own curiosity and education. Never too old to learn.

0 Kudos
Message 9 of 16
(7,796 Views)

Okay guys - I think I've got a solution using pointers. I think it makes sense, and I'm hoping I'm not doing anything incorrect.

 

As an aside - I use local variables quite a bit, mostly to reduce wire-clutter. This may be frowned upon,  but believe me, some of the VIs we have are a bloody unreadable mess because the guy before me  stuck with that hardline philosophy. I realize the inherent risks - race conditions - that are present with these, but I feel I'm careful enough to avoid them. 

0 Kudos
Message 10 of 16
(7,788 Views)