Текущий раздел:

Описания RDS

Приложения

Приложение А. Функции, константы и структуры RDS

А.5. Сервисные функции и макросы RDS

А.5.1. Доступ к сервисным функциям RDS

# Приложения

## Приложение А. Функции, константы и структуры RDS

### А.5. Сервисные функции и макросы RDS

Описываются функции, экспортированные из главного модуля RDS («rds.exe»), которые могут вызываться моделями блоков для взаимодействия с RDS и между собой, а также различные макроопределения.

#### А.5.1. Доступ к сервисным функциям RDS

Сервисные функции RDS – это функции, экспортированные из программы «rds.exe» или «rds64.exe». Все они имеют тип RDSCALL: аргументы функции передаются в стеке справа налево, стек освобождается вызванной функцией. Для доступа к сервисной функции следует получить указатель на нее при помощи функции Windows API GetProcAddress, привести этот указатель к правильному типу, учитывающему типы параметров и возвращаемого значения этой функции (тип указателя на каждую функцию приводится в описании этой функции в данном приложении), после чего можно будет вызывать эту функцию непосредственно по указателю на нее. Поскольку получить указатели на сервисные функции достаточно один раз в момент загрузки DLL с моделью блока, удобнее всего сделать это в главной функции этой DLL.

Чтобы не получать вручную все указатели на все сервисные функции, можно воспользоваться файлом «RdsFunc.h». Для этого следует включить в исходный текст программы следующий фрагмент:

      #define RDS_SERV_FUNC_BODY имя_функции
      #include <RdsFunc.h>

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

      rdsSetSystemInt(RDS_SSIWAITCURSOR,1);

будет означать, что функция, указатель на которую находится в глобальной переменной rdsSetSystemInt, вызывается с параметрами «RDS_SSIWAITCURSOR» и 1. Поскольку переменная с именем rdsSetSystemInt имеет правильный тип указателя на функцию с нужными типами параметров, ее можно использовать вместо имени функции без всякого приведения типов.

Если функция работает со строками, ситуация несколько сложнее. Такие функции существуют в RDS в двух версиях: для кодировки UTF8 с суффиксом «A» и для кодировки UTF16 с суффиксом «W». Например, для вывода пользователю сообщения в кодировке UTF8 (если файл исходного текста программы записан в этой кодировке) при помощи функции rdsMessageBox необходимо сделать следующий вызов:

      rdsMessageBoxA("Сообщение","Заголовок",MB_OK);

Вывод этого же сообщения, заданного в кодировке UTF16, делается вызовом функции с суффиксом «W» (при этом строки в параметрах функции имеют префикс «L» согласно синтаксису язака C):

      rdsMessageBoxW(L"Сообщение",L"Заголовок",MB_OK);

Для функций, имеющих дело со строками, «RdsFunc.h» вводит по две глобальных переменных с соответсвующими суффиксами. В примере выше это «rdsMessageBoxA» и «rdsMessageBoxW». Кроме того, если перед командой «#include» для «RdsFunc.h» специально не включить описание константы RDS_NO_UTFALIASES, будет дополнительно создано макроопределение для функции-псевдонима без суффикса, то есть «rdsMessageBox». По умолчанию функции-псевдонимы соответствуют версиям для кодировки UTF8, поэтому вместо «rdsMessageBoxA» можно писать просто «rdsMessageBox». Если необходимо, чтобы псевдоним без суффикса соответсвовал версии для кодировки UTF16, необходимо описать перед включением «RdsFunc.h» константу RDS_UTF16DEFAULT:

      #define RDS_SERV_FUNC_BODY имя_функции
      #define RDS_UTF16DEFAULT
      #include <RdsFunc.h>

В этом случае можно будет не писать у функций суффикс «W», если в их параметрах передаются строки в кодировке UTF16 – например, писать «rdsMessageBox» вместо «rdsMessageBoxW».

Если перед включением файла «RdsFunc.h» не будет определен макрос RDS_SERV_FUNC_BODY, все описания глобальных переменных будут включены с ключевым словом extern, то есть они будут описаны как внешние, находящиеся в другом модуле. Таким образом, если проект DLL состоит из нескольких модулей, в каждом из них нужно включить файл «RdsFunc.h», и в одном и только одном из них (обычно в том, в котором находится главная функция DLL) перед этим включением определить макрос RDS_SERV_FUNC_BODY. В результате в одном модуле будут описаны глобальные переменные-указатели на функции и функция их заполнения, а во всех остальных эти же переменные будут описаны как внешние. Это даст возможность вызывать сервисные функции по имени в любом из модулей проекта.

Для управления описаниями в файле «RdsFunc.h» можно использовать еще две дополнительных константы. Если перед включением этого файла объявить define-константу RDS_NOEXTERNFUNCPTRS (константа может не иметь значения, важен сам факт описания), внешние описания глобальных переменных-указателей на функции с ключевым словом extern не будут включены в исходный текст модуля. Если перед включением файла описать константу RDS_NOHOBJMACROS, не будут определены макросы работы со вспомогательными объектами, описанные в приложении А.5.23 и далее. Эти две константы позволяют исключать из программы описания, которые по каким-либо причинам не нужны разработчику моделей.

Примеры доступа к сервисным функциям RDS приведены в §2.2 руководства программиста и А.2.2 приложений.

См. также

Сервисные функции со строковыми параметрами.