m3nth Posted June 19, 2005 Report Share Posted June 19, 2005 This is as much a Windows/C++ question as it is a LabVIEW question. What code or mechanism can be placed in a DLL so that it can be stopped prematurely if necessary? If anyone has example C++ code that would be great. My ideas are somewhat along the lines of obtaining some sort of handle or reference (to whatever... a boolean variable, notifier, occurence, or some non-LabVIEW lower-level Windows mechanism) then passing that to the DLL and checking it periodically in case the user wants to exit early before the DLL is done. If that's somewhat going in the right direction then I'm either: A) ...Trying to figure out how to check the value of a given variable or session that I pass the DLL a reference to (how to get that coded into the DLL), - or - B) ...Trying to figure out what Windows calls I should look at on MSDN that will give me a signalling mechanism. Besides it actually functioning, the other thing I would prefer is that it doesn't take a lot of time. Therefore I am looking for not just something that works, but an optimal solution in terms of minimum processor delay and minimum CPU instructions executed... preferrably not calling a function that interrupts the DLL by going off and executing half of the Windows kernel Quote Link to comment
Rolf Kalbermatter Posted June 20, 2005 Report Share Posted June 20, 2005 This is as much a Windows/C++ question as it is a LabVIEW question.What code or mechanism can be placed in a DLL so that it can be stopped prematurely if necessary? If anyone has example C++ code that would be great. My ideas are somewhat along the lines of obtaining some sort of handle or reference (to whatever... a boolean variable, notifier, occurence, or some non-LabVIEW lower-level Windows mechanism) then passing that to the DLL and checking it periodically in case the user wants to exit early before the DLL is done. If that's somewhat going in the right direction then I'm either: A) ...Trying to figure out how to check the value of a given variable or session that I pass the DLL a reference to (how to get that coded into the DLL), - or - While this can work and it can be done easily it is not always a good solution. What you would do is adding a function to be called by LabVIEW to set somewhere a global. In your DLL check this global periodically if you have some lengthy operation. B) ...Trying to figure out what Windows calls I should look at on MSDN that will give me a signalling mechanism. This would be best solved with Windows events. Checkout http://msdn.microsoft.com/library/default....n_reference.asp While waiting on events does basically use 0% CPU you still have a problem that you would want to actually do something in your DLL. So you can't wait on an event for long periods of time as your abort event would be not the main task you would want to perform in your DLL function after all. This makes the use of events somewhat difficult. That said, Windows APIs often support asynchronous operation. For the ReadFile(), and WriteFile() function, which is what you would use almost always for any sort of IO, you can use the so called overlapped mode. You have to open the file or device with specific flags to enable overlapped access and pass in an event handle in a special structure to the read or write function and the function returns immediately to the caller. Then you can do other things and the function will trigger the event as soon as the operation is ready or you can abort the operation with a different call if it takes to long for your feeling. Overlapped mode in Windows is a little tricky, also because it is not very simple to debug asynchronous program code properly, but it can give you seemingly fast operation and still keep your application responsive to user interaction. Rolf Kalbermatter Quote Link to comment
m3nth Posted June 20, 2005 Author Report Share Posted June 20, 2005 While this can work and it can be done easily it is not always a good solution. What you would do is adding a function to be called by LabVIEW to set somewhere a global. In your DLL check this global periodically if you have some lengthy operation.This would be best solved with Windows events. Checkout http://msdn.microsoft.com/library/default....n_reference.asp While waiting on events does basically use 0% CPU you still have a problem that you would want to actually do something in your DLL. So you can't wait on an event for long periods of time as your abort event would be not the main task you would want to perform in your DLL function after all. This makes the use of events somewhat difficult. That said, Windows APIs often support asynchronous operation. For the ReadFile(), and WriteFile() function, which is what you would use almost always for any sort of IO, you can use the so called overlapped mode. You have to open the file or device with specific flags to enable overlapped access and pass in an event handle in a special structure to the read or write function and the function returns immediately to the caller. Then you can do other things and the function will trigger the event as soon as the operation is ready or you can abort the operation with a different call if it takes to long for your feeling. Overlapped mode in Windows is a little tricky, also because it is not very simple to debug asynchronous program code properly, but it can give you seemingly fast operation and still keep your application responsive to user interaction. Rolf Kalbermatter 5057[/snapback] The information and links on MSDN were very good although reading them shed further light on which direction I think I should take. Even though you pointed out that the first option (looking at some type of globally available variable) is not always a good solution, the information and event functions available through Windows don't seem to fit what I'm doing well because: - The check to see if the DLL should exit will be a poll-type check that occurs every so often when the DLL loops - Waiting for an event so that the CPU goes to 0% is bad (in my case anyway--I know it's not usually bad but it would be for me to shut down the DLL processing) - Even waiting a minimum time might be doable, but it would be bad if the check was done inside a nested loop--in comparison to a global value comparison that would take a fraction of the time. That said... do you know of any code examples that are similiar in function to the first option described? It seems to me if you were dealing strictly in C++ you could just pass the DLL function a pointer to some data and then change the data when you want the DLL to exit. With LabVIEW though the data that you would be passing the DLL a pointer to would be copied (in my best understanding) and you wouldn't really be able to change it after you passed it to the DLL. Quote Link to comment
m3nth Posted June 20, 2005 Author Report Share Posted June 20, 2005 After talking with a colleague, I have come upon the ideal solution. The DLL will simply have two functions: - The "Start" function will start and run indefinitely once it is started from LabVIEW (designated as re-entrant) - The "Stop" function will simply set a stop flag that is polled by the main routine Since the DLL memory space is shared, the variable set with the "Stop" routine will be the same variable being polled for an early exit. Here's the test code... it works nicely: _declspec(dllexport) void Stop(void); _declspec(dllexport) void Start(void); int StopFlag = 0; unsigned int i = 0; __declspec(dllexport) void Stop(void) { StopFlag = 1; } __declspec(dllexport) void Start(void) { StopFlag = 0; do // do whatever... { i += 1; } while (!StopFlag && i != 0); //timeout after 2^32 iterations if Stop hasn't been called } Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.