We are using TestStand 2.0 and Lab Windows CVI 8. We have a DLL function that uses the CVI standard prototype adaptor. In that function a device id is obtained via ibdev(). This device id is then past back up to a TestStand sequence parameter. This parameter is then passed to other steps and sequences that need it to control the instrument.
I notice that the help for ibdev() says “The unit descriptor is a temporary identification number used by the handler and is not related to the GPIB address.” How temporary is this id? In other words, if a device id is obtained in a DLL function and then the DLL is unloaded and reloaded is that device id still valid? I know we would still have the value of that id stored in the sequence parameter but is that value still valid as an id. This seems to work but I want to make sure it isn’t by coincidence. Also what about the general case of any pointer obtained in a dll, is that value still a valid pointer after the dll is unloaded and reloaded?
CVI will close anything (handles, pointers, etc) after they are unloaded from memory. With TestStand, each step has a setting for when to load and unload the code module. There are a lot of different options available for this including not unloading until the sequence file is unloaded or unloading after execution. Whichever you choose, that will determine how long those handles and pointers are valid.
I want to clarify my question. My understanding about DLLs is that they never own anything. The book Programming Applications for Microsoft Windows (forth edition page 677)says, (begin quote)...any objects created by code in the DLL's functions are owned by the calling thread or process [TesStand in this case] - a DLL never owns anything. (end quote) So if the DLL is unloaded by TestStand wouldn't the handles allocated by calls to the DLL functions still be allocated and therefore valid. I realize that when the DLL is reloaded the handle value stored in the DLL variable will probably no longer be correct but since we saved the handle to a TestStand parameter isn't that value still a valid handle since the handle is owned by the TestStand and not the DLL?
The actual calling thread is the Adapter you are using. Also, since you are calling a LabWindows/CVI DLL, you are still using the LabWindows/CVI Runtime Engine which means it is handling some of the memory management (including references and pointers). So in a way you are right, the DLL does not own these, the adapter/CVI Runtime Engine owns it. If you leave that open then you should be able to use the handle through TestStand (storing it as a variable or however you are doing it). Are you seeing behavior that contradicts this?
I'm not sure if the behavior contradicts it or not. What I'm seeing is that a device ID obtained from ibdev() and saved in a TestStand parameter is still able to be used to control an instrument even after the DLL is unloaded and reloaded. My interpretation of your first reply is that since the code module (the DLL) was unloaded and reloaded that the device ID should have been invalid. I think what your saying in your second reply is that as long as the adapter/CVI Runtime Engine remains open then the handle would remain valid even if the DLL is unloaded and reloaded. So I guess the logical follow up question would be, how do I insure that the adapter/CVI Runtime Engine remains open through out a test execution?
Under the sequence file properties you will find two settings, Load Option and Unload Option. If you select Load Dynamically and Unload after sequence executes respectively, your DLL will be loaded the first time a step accesses it, and then unloaded only when the sequence finishes.
James,
Are you implying that if the DLL unloads that the runtime engine will also close? If not, how do I allow the DLL to unload and yet keep the runtime engine open?
Everytime you load a DLL, it loads a copy of the Runtime Engine, as long as a DLL is still loaded, the Runtime Engine will stay loaded. If you close the DLLs and there are no longer any DLLs loaded, then the RTE will unload as well. So if you want to unload a DLL and keep the runtime engine, have another step that keeps the code module loaded for longer.
Thanks for all the help. I was operating under a false assumption. I assumed that when the sequence load option is set to “Preload when execution begins” and the unload option is set to “Unload after step executes” that the DLL would be unloaded after each step. What actually happens in that case is that the DLL remains loaded through out the test execution. So while I thought the device handle was remaining valid even after the DLL unloaded and reloaded what was actually happening is that the DLL was remaining loaded. I changed the load option to Load dynamically and then the DLL unloads between steps. The handle does becomes invalid when DLL is unloaded and reloaded.