Jump to content

How does LabVIEW get an image in memory?


mooner

Recommended Posts

How does LabVIEW get an image in memory. The pointer to the image in memory and the width of the image as well as the height are known. Which function should I call? Attached is a DLL prototype that outputs the pointer and size of the picture. I need to call the DLL to get the picture

dll.PNG

Link to comment

I am definitely not an expert on this kind of stuff, but I think you would first "create" a datastructure big enough to hold your image in LabVIEW. The type does not actually matter as long as it is big enough (1 byte * width * height) and then pass that into your DLL call as the first input parameter, followed obviously by the width and height.

After the DLL call the data should now have been copied into that datastructure (i.e. the wire itself will have the image on it).

I get easily confused with pointers to pointers, so might have this completely wrong.

Sorry I have not explained this very well. Can you attach your DLL?

Edited by Neil Pate
Link to comment
7 hours ago, mooner said:

The pointer to the image in memory and the width of the image as well as the height are known

And what's the image data type (U8, U16, RGB U32, ...)? You need to know this as well to calculate the buffer size to receive the image into. Now, I assume, you first call the CaptureScreenshot function and get the image pointer, width and height. Second, you allocate the array of proper size and call MoveBlock function - take a look at Dereferencing Pointers from C/C++ DLLs in LabVIEW ("Special Case: Dereferencing Arrays" section). If everything is done right, your array will have data and you can do further processing.

Edited by dadreamer
Link to comment
On 10/23/2023 at 6:49 PM, Neil Pate said:

I am definitely not an expert on this kind of stuff, but I think you would first "create" a datastructure big enough to hold your image in LabVIEW. The type does not actually matter as long as it is big enough (1 byte * width * height) and then pass that into your DLL call as the first input parameter, followed obviously by the width and height.

After the DLL call the data should now have been copied into that datastructure (i.e. the wire itself will have the image on it).

I get easily confused with pointers to pointers, so might have this completely wrong.

Sorry I have not explained this very well. Can you attach your DLL?

Thank you, your explanation is very clear. I have solved my problem so far and the solution is basically the same as you said.

Link to comment
On 10/24/2023 at 1:04 AM, dadreamer said:

And what's the image data type (U8, U16, RGB U32, ...)? You need to know this as well to calculate the buffer size to receive the image into. Now, I assume, you first call the CaptureScreenshot function and get the image pointer, width and height. Second, you allocate the array of proper size and call MoveBlock function - take a look at Dereferencing Pointers from C/C++ DLLs in LabVIEW ("Special Case: Dereferencing Arrays" section). If everything is done right, your array will have data and you can do further processing.

Thank you very much for your reply. After your guidance, I re-learned the use of "MoveBlock" and found that this function is indeed a very powerful thing, and I have solved my problem by using it so far. Attached is a screenshot of my code, thanks again!

code.PNG

frontPanel.PNG

Link to comment
20 hours ago, mooner said:

Thank you very much for your reply. After your guidance, I re-learned the use of "MoveBlock" and found that this function is indeed a very powerful thing, and I have solved my problem by using it so far. Attached is a screenshot of my code, thanks again!

code.PNG

 

What does the documentation say about the pointer returned by the function? Is it allocated by the function? Is it a static buffer that is always the same (very unlikely)?

If it is allocated by the function, you will need to deallocate it after use (after the MoveBlock() function), and the documentation should state what memory manager function was used to allocate the buffer and what memory manager function you should use to deallocate it, otherwise you create a memory leak every time you call this function.

Ideally the DLL exports a function that will deallocate the buffer, still a usable solution is if they use the Windows GlobalAlloc() function to create the buffer in which case you would need to call GlobalFree(). Pretty bad would be if they use malloc(). This is because the malloc() call that the DLL does might be linking to a different version of the C runtime library than the according free() you will try to call in LabVIEW, and that is a sure way to create trouble.

Edited by Rolf Kalbermatter
Link to comment
6 hours ago, Rolf Kalbermatter said:

What does the documentation say about the pointer returned by the function? Is it allocated by the function? Is it a static buffer that is always the same (very unlikely)?

If it is allocated by the function, you will need to deallocate it after use (after the MoveBlock() function), and the documentation should state what memory manager function was used to allocate the buffer and what memory manager function you should use to deallocate it, otherwise you create a memory leak every time you call this function.

Ideally the DLL exports a function that will deallocate the buffer, still a usable solution is if they use the Windows GlobalAlloc() function to create the buffer in which case you would need to call GlobalFree(). Pretty bad would be if they use malloc(). This is because the malloc() call that the DLL does might be linking to a different version of the C runtime library than the according free() you will try to call in LabVIEW, and that is a sure way to create trouble.

Thanks for the heads up! Indeed the program was running with a memory leak. My code also needs to call the function where the DLL frees the memory. I tested it and the modified program does avoid the memory leak problem.

free.PNG

Link to comment
1 hour ago, MikaelH said:

Also try running the DLL in any thread.
That will probably speed up the execution >100 times, but if the DLL is not thread safe you might get crashes.
image.png.1e7cc65c655b61006138b529f035f6f1.png

That is a tricky recommendation, as you explain too. Unless it is documented that the DLL or particular function is thread safe, I would normally refrain from calling the function in any thread.

Also your claimed speed improvement is very off, especially in this case. The main time loss is when the LabVIEW program has to wait for the UI thread to be available for calling the CLN. This is at worst in the order of a few ms, typically even significantly below 1 ms. Compared to the runtime of these functions, which for the capture does a GDI bitmap copy and some extra shuffling to only get out the actual pixel data and for the MoveBlock(), which does a memory copy of a significant size, this delay of arbitrating for the UI thread is pretty small. It's likely measurable with the high resolution timer, but do you really care if this VI takes 25 ms to execute or 26 ms?

Reentrant execution of a CLN gets really interesting performance wise when you have a short running function which is called over and over again in a loop. Here the overhead of arbitrating each time for the UI thread will be significant and can get even the single most dominating factor in the execution speed.

There is one other aspect about not wanting to run a CLN in the UI thread. While LabVIEW is busy executing the CLN in the UI thread, this thread is not available to do anything else, including drawing anything on the screen and processing Windows events such as mouse and keyboard events. If the CLN takes a long time to execute (many 100 ms to seconds) the LabVIEW application will appear to be frozen during the call to this CLN (and in the worst case Windows will notice after several seconds that the event loop isn't polled for a long time and provide the user with a dialog suggesting that the application is unresponsive and should probably be shut down).

Edited by Rolf Kalbermatter
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.