Открытие и закрытие связи с устройством

Адаптеры, обычно открытые связь с устройством в их openDevice() функционируйте и закройте связь в их closeDevice() функция. Для большинства устройств, открывая связь с устройством резервирует его для исключительного использования. Закрытие устройства выпускает устройство.

Примечание

Механизм тулбокса на самом деле вызывает IAdaptor класс open() функция членства, чтобы открыть связь с устройством и close() функционируйте, чтобы закрыть связь с устройством. Они функционируют, затем вызывают openDevice() вашего адаптера и closeDevice() функции. Если ваш адаптер должен открыть или закрыть устройство, используйте open() и close() функции, вместо того, чтобы вызвать openDevice() или closeDevice() непосредственно.

Предложенный Алгоритм для openDevice ()

openDevice() функция обычно выполняет следующие задачи.

  1. Протестируйте, открыто ли устройство уже путем вызова IAdaptor класс isOpen() функция. Если устройство уже открыто, ваш openDevice() функция должна возвратить true. Если устройство не уже открыто, ваш openDevice() функция должна установить связь с устройством с помощью вызовов SDK устройства.

  2. Запустите поток захвата. Смотрите Запуск Потока Захвата для получения дополнительной информации.

    Примечание

    Запуск отдельного потока только требуется, если ваш адаптер использует основанный на потоке проект. Адаптеры могут также использовать асинхронные прерывания (коллбэки), чтобы получить системы координат, если устройство поддерживает это. В этом сценарии адаптеры получают уведомление асинхронно, когда данные доступны. Для получения информации об использовании этого метода обратитесь к документации для SDK своего устройства.

Запуск потока захвата

Чтобы запустить поток захвата, используйте Windows® CreateThread() функция. CreateThread() функция создает поток, который выполняется в виртуальном адресном пространстве процесса вызова.

CreateThread() функция принимает эти параметры.

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  SIZE_T dwStackSize,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID lpParameter,
  DWORD dwCreationFlags,
  LPDWORD lpThreadId
);

Для адаптера следующая таблица приводит параметры, которые необходимо установить. Для полной информации о создании потока смотрите Microsoft Docs.

Параметр

Описание

lpStartAddress

Адрес захвата распараллеливает процедуру. Задайте имя процедуры потока, объявленной в вашем заголовочном файле класса адаптера. Смотрите Реализацию Функции Потока Захвата.

lpParameter

Указатель на сам объект, т.е. this указатель.

lpThreadId

Адрес переменной, в который CreateThread() функция возвращает ID, присвоенный недавно созданному потоку

После того, как вы вызываете CreateThread() функция, приложения обычно вызывают PostThreadMessage() функция, чтобы отправить сообщение в новый поток. Это заставляет систему создавать очередь сообщений для потока. Введите цикл, чтобы ожидать, пока поток не подтверждает, что сообщение было получено, чтобы гарантировать, что очередь потока была создана. Ваш адаптер отключает поток в closeDevice() вашего адаптера функция — видит Предложенный Алгоритм для closeDevice ().

Пример: открытие связи

Этот пример показывает скелетную реализацию openDevice() функция.

  1. Замените тупиковую реализацию openDevice() функция в MyDevice адаптер с этим кодом.

    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;
    }
    
  2. Чтобы смочь скомпилировать и соединить ваш адаптер, необходимо создать тупиковую реализацию acquireThread() функционируйте и добавьте его в свой адаптер. Можно заполнить полноценное внедрение позже — смотрите Реализацию Функции Потока Захвата.

    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
    
  3. Добавьте объявления acquireThread() функция, acquireThread переменная и acquireThreadID переменная как частные элементы данных вашего заголовочного файла класса адаптера. В этом примере, 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;
    
  4. Скомпилируйте и соедините свой адаптер. Необходимо смочь создать объект ввода видео. Когда вы вызываете start функционируйте, проверьте, что ваш адаптер успешно создал поток захвата.

Предложенный Алгоритм для closeDevice ()

closeDevice() функция обычно выполняет следующие задачи.

  1. Протестируйте, закрывается ли устройство уже. Если это, выход.

  2. Добавьте сообщение к потоку захвата, чтобы выйти и ожидать, пока он не возвратится перед выходом для адаптеров с основанными на потоке проектами. Для получения дополнительной информации о добавлении сообщения к потоку, смотрите Отправку сообщения к Потоку Захвата.

  3. Закройте указатель, сопоставленный с потоком захвата, и сбросьте переменную указателя потока к NULL.

Пример: закрытие связи с устройством

Пример показывает скелетную реализацию closeDevice() функция.

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;
}