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.
The openDevice()
function typically performs
the following tasks.
Test whether the device is already open
by calling the IAdaptor
class isOpen()
function.
If the device is already open, your openDevice()
function
should return true
. If the device is not already
open, your openDevice()
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.
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 Docs.
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().
This example shows a skeletal implementation of an openDevice()
function.
Replace the stub implementation of the openDevice()
function
in the MyDevice
adaptor with this code.
bool MyDeviceAdaptor::openDevice() { // If device is already open, return true. if (isOpen()) return true; // Create the image acquistion 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,
the acquireThread
variable, and the acquireThreadID
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.
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
.
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; }