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

Адаптеры, обычно открытые связь с устройством в их 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® Developer Network (msdn.microsoft.com).

Параметр

Описание

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;
}
Для просмотра документации необходимо авторизоваться на сайте