08-29-2009 09:54 AM
Hi everyone,
I have a DLL which open and reads some values from a camera. The function looks like:
initialize();
read();
close();
I want to read these values continously. If I put the call library funtion in a while loop it will loose a lot of time initialising and closing the camera for each reed. I tought that I can rewrite the DLL in this way:
initialize();
while(bool)
read();
close();
My concern is: if I pass bool as a normal argument of the DLL I will be read only when the DLL is called and it won't see the change while it is executing,no?
So the question is, how to pass a parameter (for example a control in front panel) to a DLL while it is is running?
I tought that I can create a global (for the vi and the funtion in the DLL) in such a way that the DLL will see its changing while executing, is it possible? Or I can maybe pass to the DLL as an argument the address of the bool variable to be changed from front panel...how?
Thank you
08-30-2009 02:33 AM
Basically you can't. The control is updated in the UI thread of LabVIEW when that thread gets around to be scheduled byt the OS and when LabVIEw has done all the other things it needs to do in that thread because they need to be protected from concurrent access. So there is not a pointer you can grab and have some arbitrary component update the information on the screen directly. Also consider that while you might update a numeric, LabVIEW's update routine has to draw a string representing that numeric, and the same happens with an image for instance.
The only difference to this is the IMAQ control, whose operation is reference based, but the API to access such controls directly from C is undocumented and private so far and therefore can change with any new version of LabVIEW (and likely has with the introduction of 64Bit support in IMAQ Vision).
What you can do is pass a buffer to your DLL and have it update that and then pass that buffer to the control. Anything else is a major pita to even think about.
But maybe if you do get a lot more specific about what it is exactly that you want to do, we could give you alternatives or better ways to do what you want to do.
Rolf Kalbermatter
08-30-2009 10:02 AM
I newer tried, but think that the following thing should work.
If you create in additional to your main dll another one, that runs inside Labview loop.
There should be one common parameter to two dll's - pointer to value.
From here on,you can do whatever you whant with this pointer (some kind of producer/consumer 🙂 ).
08-30-2009 12:27 PM
how can you pass a pointer between two dll in labview? won't the allocated memory in the first dll be deleted when it is closed? who can guarantee the validity of the pointer passed to the second dll. and which is the lv type for pointers? in my case this pointer has type defined by the provider of my application so I don't know its size.
rolfk, could you explain better
"pass a buffer to your DLL and have it update that and then pass that buffer to the control"
in my case the read() function returns an array of doubles. if it runs n times then it will return a matrix. how can i pass this (let's think about the first case) to labview?
thank you
08-31-2009 01:42 AM - edited 08-31-2009 01:46 AM
Well you have basically two possibilities with buffers passed to a function. The most common is that the caller allocates a large enough buffer and passes it to the function to be filled in. You do that in LabVIEW for instance with the Initialize Array function and passing that array correctly to the DLL function.
The other is that the function allocates a pointer and returns it. This is not compatible with LabVIEW. It can be done but only with an intermediate wrapper function that needs to be implemented in C. And that is anything but trivial depending on the function and how the memory needs to be allocated/managed/released.
A third thing is that you do allocate a buffer in the caller but the DLL will fill it in after the function returns. This is also not compatible with LabVIEW, since LabVIEW reserves the right to manage its memory anyway it wants and only guarantees a buffer to be valid for the duration of the function call. If you do need this, then the best solution is also to create an intermdiate wrapper, just as above.
But this wrapper is certainly advanced C programming so if you haven't done a C programming course yet, it would be a good time to start, before attempting this.
Rolf Kalbermatter
08-31-2009 09:32 AM
Hi rolfk,
May be something like this - some kind of "quick and dirty",
includes cast from value to pointer
and not thread- safe, but does the work - stops C++ loop from labview
09-01-2009 12:57 AM - edited 09-01-2009 12:58 AM
mishklyar wrote:Hi rolfk,
May be something like this - some kind of "quick and dirty",
includes cast from value to pointer
and not thread- safe, but does the work - stops C++ loop from labview
Nice idea in theory, but in practice it will not work well. The problem here is that you retrieve the pointer to a variable that you pass in from LabVIEW. You would have to make sure that the wire you optained this pointer from stays valid (and is not relocated by LabVIEW) as long as you want to use the other two functions on that pointer. If you use them all in one single diagram level you can do that but the advantage of asynchronous operation is usually moot if you work in the same diagram level anyhow.
But as soon as you cross diagram structure boundaries (loops, cases, sequences and expecially subVI) you will get a very hard time and in the case of subVIs basically no way at all, to guarantee that the pointer stays valid. A single branch on that wire on the LabVIEW diagram can also throw it all off. So it may be a hack you can use by very carefully drawing your diagram, but in no way is it something you could use in a library, especially if others are supposed to use those functions too.
Rolf Kalbermatter