Создание панелей функций NI LabWindows™/CVI™ из файлов заголовков

Overview

LabWindows/CVI предлагает различные средства документирования исходного кода, что делает процесс написания кода более простым и удобным для разработчиков. Одним из таких средств является способность генерировать панели функций из файлов заголовков с помощью тегов ///.

Используя теги файлов заголовков, Вы можете ускорить процесс создания панелей функций, одновременно открывая их преимущества, такие как возможность легко генерировать и тестировать вызовы функций в LabWindows/CVI и выполнять эти функции в окне Interactive Execution немедленно.

В этом руководстве подробно рассматриваются различные теги файлов заголовков (.h), включая примеры использования.

Contents

Генерация панели функций

Если Вы откроете файл заголовка/включения (.h) в LabWindows/CVI, Вы можете создать панель функций, используя команду Options»Generation Function Tree (Параметры»Генерация дерева функций).  Чтобы четко определить структуру дерева функций, Вы должны использовать теги файлов заголовков.  С другой стороны, если Вы генерируете панели функций из файла заголовка, который не включает теги файла заголовка, все панели функций будут расположены в корне дерева инструментов, и все параметры будут созданы как входные данные.

Рис. 1. Диалог создания дерева функций

Например, если Вы сгенерируете панель функций из следующего файла заголовка, результирующий файл панели функций (.fp) будет выглядеть как на рис. 2. Обратите внимание на плоскую структуру дерева на панели функций.

int __stdcall fn1(int a);
int __stdcall fn2(int b);
int __stdcall fn3(int a, int b);

float __stdcall fn4(float a);
float __stdcall fn5(float b);
float __stdcall fn6(float a, float b);

Рис. 2. Сгенерированная панель функций из файла заголовков без тегов

Примечание: Поле квалификатора по умолчанию в диалоговом окне Generate Function Tree (Создать дерево функций) должно соответствовать полю квалификатора по умолчанию, используемому в исходном файле заголовка. 

Используя теги файлов заголовков, обозначенные /// ключевые слова, у Вас есть возможность:

  • упорядочить функции
  • настроить имена функций
  • изменить типы параметров управления и имена
  • добавить настройку параметров
  • отобразить значения по умолчанию
  • добавить справку к функциям, параметрам и классам
  • и многое другое.

Добавление иерархии с классами

Во-первых, для создания иерархии в файле .fp Вы можете использовать классы. Следующий тег идентифицирует начало класса:

/// -> Имя класса

Следующий тег указывает на конец класса:

/// <- Имя класса

Примечание: Для этого тега имя класса является необязательным и помогает улучшить читаемость кода. Кроме того, теги -> и <- могут быть вложенными.

Пример

/// -> Integers
int __stdcall fn1(int a);
int __stdcall fn2(int b);
int __stdcall fn3(int a, int b);
/// <- Integers

/// -> Floats
float __stdcall fn4(float a);
float __stdcall fn5(float b);
float __stdcall fn6(float a, float b);
/// <- Floats

На рис. 3 показаны получившиеся панели функций, сгенерированные из приведенного выше кода.

Рис. 3. Сгенерированные панели функций с тегами ->

Исправление имен функций

Чтобы создать согласованный стиль для автоматически сгенерированных панелей функций, для каждой создаваемой панели функций LabWindows/CVI выполняет следующие действия:

  • Удаление префикса функции
  • Первая буква делается прописной
  • Вставка пробела перед каждой первой прописной буквой или цифрой в группе заглавных букв или цифр.  Например, Set6100SensorRpms изменяется на Set 6100 Sensor Rpms

Имя сгенерированной панели функций может отличаться от предполагаемого имени из-за механизма автоматического разделения слов. Для коррекции сгенерированных названий панелей функций используйте тег XCHG. Также Вы можете указать несколько пар строк для замены, разделенных запятыми.

Примечание: Для замены строк в элементах управления панели функцийВы также можете использовать тег PXCH.

Пример

/// XCHG Fn/Function
/// -> Integers
int __stdcall fn1(int a);
int __stdcall fn2(int b);
int __stdcall fn3(int a, int b);
/// <- Integers

/// -> Floats
float __stdcall fn4(float a);
float __stdcall fn5(float b);
float __stdcall fn6(float a, float b);
/// <- Floats
/// XCHG

На рисунке 4 показана панель функций, сгенерированная из кода, приведенного выше.

Рис. 4. Сгенерированные панели функций с тегами XCHG

Добавление специализированных типов данных

Поскольку генератор панели функций не основан на компиляторе и не анализирует типы данных, определенные в файлах заголовков, любое использование типов данных не-ANSI приведет к синтаксической ошибке. Чтобы исправить это, используйте тег ADDT. Это позволит генератору быть в курсе о любых специализированных типах данных, которые Вы собираетесь использовать в файле заголовков.

Пример

/// ADDT int8
/// ADDT uInt8

Генератор добавит на панели функций имя типа плюс некоторые производные типы массивов и указателей.

 

int8
int8 []
int8 *
int8 **
int8 ***
int8 *[]
            uInt8
uInt8 []
uInt8 *
uInt8 **
uInt8 ***
uInt8 *[]

 

Создание элементов управления Ring, Slider и Binary Switch

По умолчанию генератор панелей функций создает элементы управления для ввода. С другой стороны, если генератор обнаруживает тип enum, он автоматически создает для этого параметра элемент управления Ring. Однако, у Вас есть возможность создавать элементы управления других типов с помощью тегов RNG, SLD и BIN.

Каждый тег требует двух параметров, разделенных косой чертой. Первый параметр - это положение ( одномерный индекс), а второй параметр является необязательным и может представлять имя enum, если тип данных параметра функции имеет тип enum

Примечание: Тег BIN может быть связан только с перечислением, которое имеет ровно два значения.

Пример

typedef enum {
    ON=1,
    OFF=0,
} MyBinaryEnumType;

/// BIN 1
int __stdcall fnX(MyBinaryEnumType binaryInput);

Рис. 5. Элемент управления Binary

Если Вы хотите использовать набор значений, которые определены с помощью команды препроцессора #define, то Вы можете сгруппировать их в поименованный enum, используя тег ENUM.

Примечание: За группой значений #define должна следовать пустая строка. Это позволит генератору распознать конец enum.

Пример

/// ENUM enum1
#define ON 1
#define OFF 0

/// ENUM enum2
#define ONE 1
#define TWO 2
#define THREE 3
#define FOUR 4

/// BIN 1/enum1
/// SLD 2/enum2,3/enum2
/// RNG 4/enum2,5/enum2
int __stdcall fnX(int a, int b, int c, int d, int e);

На рис. 6 показаны элементы управления, сгенерированные из приведенного выше кода.

Рис. 6. Созданные элементы управления с использованием тегов BIN, SLD и RNG

Если Вам нужно добавить к существующему enum дополнительное значение по умолчанию, используйте тег EHDV для элемента управления slider или binary. Генератор добавит дополнительное значение вверху списка значений, на метке появится надпись «Default» (По умолчанию), а для элемента управления будет установлено указанное значение.

Пример

typedef enum {
    kLeftAligned=0,
    kRightAlighed=1,
} AlignmentEnumType;
 

/// SLD 1
/// EHDV 1/-1
int __stdcall fnX(AlignmentEnumType alignment);

На рис. 7 показан элемент управления, сгенерированный вышеуказанным кодом.

Рис. 7. Элемент управления, сгенерированный с помощью тега EHDV

Если Вы хотите создать для элементов управления ring, binary или slider разные метки значений, то Вы можете сделать это, добавив комментарии к каждому значению enum. Генератор заменит имена значений enum текстом из комментария.

Примечание: Избегайте использования точек с запятой в комментариях enum.

 

 

Пример

typedef enum {
    kLeftAligned= 0, // Left aligned
    kRightAlighed=1, // Right aligned
} AlignmentEnumType;

/// SLD 1
/// EHDV 1/-1
int __stdcall fnX(AlignmentEnumType alignment);

 

На рис. 8 показан элемент управления, сгенерированный вышеуказанным кодом.

Рис. 8. Использование комментариев с тегом SLD

Объявление выходных параметров

Для объявления выходных параметров используйте тег OUT. Обратите внимание, что выходными параметрами могут быть только указатели и массивы. Любой другой тип данных приведет к ошибке.


Пример

/// OUT 2,3
int __stdcall Sphere_Calc(float radius, float *surface, float *volume);

На рисунке 9 показано, что генерируется из приведенного выше кода.

Рис. 9. Сгенерированные элементы управления с использованием тега OUT

Определение значений по умолчанию для параметров

Генератор панели функций создает пустые входные и выходные параметры и устанавливает все параметры типа ring, binary или slider на первый элемент. Если Вам нужно изменить значение параметра по умолчанию, используйте тег DFLT.

Пример

/// OUT 2,3
/// DFLT 1/1.0,2/&surface,3/&volume
int __stdcall Sphere_Calc(float radius, float *surface, float *volume);

На рис. 10 показаны сгенерированные элементы управления для приведенного выше кода.

Рис. 10. Элементы управления, созданные с помощью тега DFLT

Изменение типов параметров

Если Вам на панели функций нужно использовать определенный тип параметра, используйте тег PTYP, чтобы изменить его с типа данных ANSI-C на любой другой тип, который активен на панели функций. Например, параметр функции, объявленный как void* но используемый для числовых массивов, может быть изменен с void* на тип Numeric Array(Числовой массив) из LabWindows/CVI

Пример

/// PTYP 1/Numeric Array
float __stdcall CalcArrayMean(void *array, int dataType);

На рис. 11 показаны элементы управления, сгенерированные из приведенного выше кода.

Рис. 11. Элементы управления, созданные с использованием тега PTYP

Использование функций SetAttribute и GetAttribute

Для определенных атрибутов прибора в драйверах IVI часто используются файлы .SUB.  Если вашему прибору требуются функции SetAttribute или GetAttribute, атрибуты которых хранятся в файле .SUB, используйте тег ERNG для параметра атрибута и тег PTYP для параметра значения. Для параметра атрибута генератор создаст пустой ring, однако при загрузке прибора содержимое параметра ring будет заполнено атрибутами из файла .SUB. Для параметра значения генератор изменит тип параметра с void* на тип Any Type (Любой тип) из LabWindows/CVI

Примечание: Структуру файлов .sub можно найти в главе 7 Спецификации интерфейса интерактивного разработчика драйвера прибора

Пример

/// ERNG 1
/// PTYP 2/Any Type
/// OUT 2
int __stdcall GetAttribute(int attribute, void *value);

Примечание:Файлы .SUB должны находиться в той же папке, что и связанный с ними файл .fp, и иметь общее корневое имя.

Для этого примера для заполнения атрибутов прибора мы будем использовать прикрепленный файл FPGen.sub. После создания панели функций откройте функцию GetAttribute и выберите Options»Operate Function Panel(Параметры »Панель функций управления) (F9). На рис. 12 показаны элементы управления, сгенерированные из приведенного выше кода.


Рис. 12. Элементы управления, сгенерированные с использованием тега ERNG

Использование аргументов-переменных

В некоторых случаях Вам может понадобиться использовать в объявлении функции аргументы-переменные. Таким образом, если Вам нужны дополнительные элементы управления параметрами на панели функций, Вы можете добавить их, используя тег VARG.

Пример

/// VARG int/More Numbers Ending With Zero
int __stdcall Sum(int number, ...);

На рис. 13 показаны элементы управления, сгенерированные из приведенного выше кода.

Рис. 13. Элементы управления, сгенерированные с использованием тега VARG

При использовании панели функций с аргументами-переменными Вы можете ввести первое число в первом элементе управления, а остальные числа, разделенные запятыми и оканчивающиеся нулем, во втором элементе управления. В итоге вызов функции будет выглядеть так:

Sum(1, 2, 3, 4, 5, 0);

Рис. 14. Сгенерированные элементы управления с последовательностью

 

Настройка параметров

К параметрам панели функций могут быть добавлены дополнительные настройки.  Настройки обозначаются кнопкой «...» справа от элемента управления параметрами. Чтобы настроить параметр, используйте тег CUST. Укажите положение параметра, библиотеку DLL, которая содержит желаемую функцию настройки и имя точки входа. Дополнительная помощь по созданию функций настройки и DLL можно найти в справке LabWindows/CVI.

Примечание: Чтобы DLL-библиотека настройки могла быть найдена, она должна находиться в системной папке или в той же папке, где находится прибор.  В спецификации DLL Вы также можете использовать относительный или абсолютный путь.


Пример

/// CUST 1/cviLibCust.dll/SelectAnyFile
int __stdcall SaveDataToFile(char filePath[], void *data);

Для этого примера мы будем использовать прикрепленный файл cviLibCust.dll. После генерации панели функций откройте функцию SaveDatatoFile и выберите Options»Operate Function Panel (Параметры » Работа с панелью функций) (F9). Если теперь Вы нажмете кнопку настройки (или нажмете Enter с курсором внутри параметра), появится диалоговое окно Open File (открыть файл), как показано на рис. 15.

Рис. 15. Настройка параметров

Добавление справки

Кроме того, для документирования Ваших панелей функций Вы можете добавить справку для инструмента, справку для каждого класса, справку для каждой функции и даже справку для каждого параметра с помощью тегов HFP, HCL, HFUN, HPAR, а также HRET. Также Вы можете добавить справку в виде отформатированного текста HTML, но содержание справки необходимо сохранить в файле.  Каждое имя файла может быть связано с одним или несколькими тегами генерации справки.

Пример

/// HFP FPfileHelp.htm
/// HCL IntegerClassHelp.htm
/// -> Integers
/// HFUN Fn1Help.htm
/// HPAR 1/ParameterAHelp.htm
int __stdcall fn1(int a);
/// HFUN Fn2Help.htm
/// HPAR 1/ParameterBHelp.htm
int __stdcall fn2(int b);
/// HFUN Fn3Help.htm
/// HPAR 1/ParameterAHelp.htm,2/ParameterBHelp.htm
int __stdcall fn3(int a, int b);
/// <- Integers

Примечание: Ниже для справки прилагаются HTML-файлы, используемые в этом примере.

После генерации файла панели функций Вы можете установить курсор на первый параметр функции fn3 и выбрать меню Edit » Show Prototype (Изменить » Показать прототип) (или нажать Ctrl + Shift + Space). Прототип функции отобразится во всплывающей подсказке.

Вы можете вызвать справку по параметру, нажав на кнопку вопросительного знака (или нажав клавишу F1).

 

             Рис. 16. Справка по функции HTML

Ссылки по теме

Проверенная среда разработки LabWindows/CVI может повысить эффективность разработки приложений ANSI C с помощью различных инструментов документирования, включая теги исходного кода, возможность генерировать панели функций из файлов заголовков и возможность генерировать HTML-документацию из функциональных панелей.