Opening and Closing Connection with a Device
Adaptors typically open a connection with the device in their
openDevice()
function and close the connection in their
closeDevice()
function. For most devices, opening a connection to the device reserves
it for exclusive use. Closing the device releases the device.
Note
The toolbox engine actually calls the IAdaptor
class
open()
member function to open a connection with a device and
the close()
function to close a connection with a device. These
function then call your adaptor's openDevice()
and
closeDevice()
functions. If your adaptor needs to open or
close a device, use the open()
and close()
functions, rather than calling openDevice()
or
closeDevice()
directly.
Suggested Algorithm for openDevice()
The openDevice()
function typically performs the following
tasks.
Test whether the device is already open by calling the
IAdaptor
classisOpen()
function. If the device is already open, youropenDevice()
function should returntrue
. If the device is not already open, youropenDevice()
function should establish a connection to the device using device SDK calls.Start the acquisition thread. See Starting an Acquisition Thread for more information.
Note
Starting a separate thread is only required if your adaptor uses a thread-based design. Adaptors can also use asynchronous interrupts (callbacks) to acquire frames, if the device supports this. In this scenario, adaptors receive notification asynchronously when data is available. For information about using this method, refer to the documentation for your device's SDK.
Starting an Acquisition Thread
To start an acquisition thread, use the Windows®
CreateThread()
function. The
CreateThread()
function creates a thread that executes
within the virtual address space of the calling process.
The CreateThread()
function accepts these
parameters.
HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId );
For an adaptor, the following table lists the parameters you must set. For complete information about creating a thread, see Microsoft documentation.
Parameter | Description |
---|---|
| Address of the acquisition thread procedure. Specify the name of the thread procedure declared in your adaptor class header file. See Implementing the Acquisition Thread Function. |
| Pointer to the object itself, i.e., the
|
| Address of a variable in which the
|
After you call the CreateThread()
function, applications
typically call the PostThreadMessage()
function to send a
message to the new thread. This causes the system to create a message queue for
the thread. Enter a loop to wait until the thread acknowledges the message was
received to ensure that the thread queue has been created. Your adaptor
terminates the thread in your adaptor's closeDevice()
function — see Suggested Algorithm for closeDevice().
Example: Opening a Connection
This example shows a skeletal implementation of an
openDevice()
function.
Replace the stub implementation of the
openDevice()
function in theMyDevice
adaptor with this code.bool MyDeviceAdaptor::openDevice() { // If device is already open, return true. if (isOpen()) return true; // Create the image acquisition thread. _acquireThread = CreateThread(NULL, 0, acquireThread, this, 0, &_acquireThreadID); if (_acquireThread == NULL) { closeDevice(); return false; } // Wait for thread to create message queue. while(PostThreadMessage(_acquireThreadID,WM_USER+1,0,0) == 0) Sleep(1); return true; }
To be able to compile and link your adaptor, you must create a stub implementation of your
acquireThread()
function and add it to your adaptor. You can fill in the complete implementation later — see Implementing the Acquisition Thread Function.DWORD WINAPI MyDeviceAdaptor::acquireThread(void* param) { MSG msg; while (GetMessage(&msg,NULL,0,0) > 0) { switch (msg.message) { case WM_USER: // The frame acquisition loop code goes here. imaqkit::adaptorWarn(''in acquire thread function \n''); } // end switch } // end while return 0; } // end acquireThread
Add declarations of the
acquireThread()
function, theacquireThread
variable, and theacquireThreadID
variable as private data members of your adaptor class header file. In this example,MyDeviceAdaptor.h
.private: // Declaration of acquisition thread function static DWORD WINAPI acquireThread(void* param); // Thread variable HANDLE _acquireThread; // Thread ID returned by Windows. DWORD _acquireThreadID;
Compile and link your adaptor. You should be able to create a video input object. When you call the
start
function, verify that your adaptor successfully created the acquisition thread.
Suggested Algorithm for closeDevice()
The closeDevice()
function typically performs the following
tasks.
Test whether the device is already closed. If it is, exit.
Post a message to the acquisition thread to quit and wait until it returns before exiting, for adaptors with thread-based designs. For more information about posting a message to the thread, see Sending a Message to the Acquisition Thread.
Close the handle associated with the acquisition thread and reset the thread handle variable to
NULL
.
Example: Closing the Connection with a Device
The example shows a skeletal implementation of the
closeDevice()
function.
bool MyDeviceAdaptor::closeDevice(){ // If the device is not open, return. if (!isOpen()) return true; // Terminate and close the acquisition thread. if (_acquireThread) { // Send WM_QUIT message to thread. PostThreadMessage(_acquireThreadID, WM_QUIT, 0, 0); // Give the thread a chance to finish. WaitForSingleObject(_acquireThread, 10000); // Close thread handle. CloseHandle(_acquireThread); _acquireThread = NULL; } return true; }