Полный исходный текст на языке C++ для библиотеки (DLL) с моделями, использующими дополнительные переменные для управления выходными связями. Библиотека содержит две модели:
- TestSW2 – блок, передающий входное значение либо только по одной из двух выходных связей, либо по обеим;
- TestSW – блок-демультиплексор с выходом-массивом.
// Управление срабатыванием выходных связей #include <windows.h> #include <RdsDef.h> // Подготовка описаний сервисных функций #define RDS_SERV_FUNC_BODY GetInterfaceFunctions #include <RdsFunc.h> //========== Главная функция DLL ========== int WINAPI DllMain(HINSTANCE /*hinst*/, unsigned long reason, void* /*lpReserved*/) { if(reason==DLL_PROCESS_ATTACH) // Загрузка DLL { // Получение доступа к функциям RDS if(!GetInterfaceFunctions()) RDS_SERV_ERROR_MSGW // Сообщение: старая версия RDS } return 1; } //========= Конец главной функции ========= //============ Переключатель ============== extern "C" __declspec(dllexport) int RDSCALL TestSW2(int CallMode, RDS_PBLOCKDATA BlockData, LPVOID ExtParam) { // Макроопределения для статических переменных #define pStart ((char *)(BlockData->VarTreeData)) #define Start (*((char *)(pStart))) #define Ready (*((char *)(pStart+RDS_VSZ_S))) #define x (*((double *)(pStart+2*RDS_VSZ_S))) #define N (*((RDSINT32 *)(pStart+2*RDS_VSZ_S+RDS_VSZ_D))) #define L0 (*((char *)(pStart+2*RDS_VSZ_S+RDS_VSZ_D+RDS_VSZ_I))) #define L1 (*((char *)(pStart+2*RDS_VSZ_S+RDS_VSZ_D+RDS_VSZ_I+ \ RDS_VSZ_L))) #define y0 (*((double *)(pStart+2*RDS_VSZ_S+RDS_VSZ_D+RDS_VSZ_I+ \ 2*RDS_VSZ_L))) #define y1 (*((double *)(pStart+2*RDS_VSZ_S+2*RDS_VSZ_D+ \ RDS_VSZ_I+2*RDS_VSZ_L))) switch(CallMode) { // Проверка типа переменных case RDS_BFM_VARCHECK: if(strcmp((char*)ExtParam,"{SSDILLDD}")==0) return RDS_BFR_DONE; return RDS_BFR_BADVARSMSG; // Выполнение такта моделирования case RDS_BFM_MODEL: switch(N) { case 0: // Передать данные на выход y0 y0=x; L0=1; // Разрешить y0 L1=0; // Запретить y1 break; case 1: // Передать данные на выход y1 y1=x; L0=0; // Запретить y0 L1=1; // Разрешить y1 break; default: // Передать данные на оба выхода y0=y1=x; L0=L1=1; // Разрешить оба выхода } break; } return RDS_BFR_DONE; // Отмена макроопределений #undef y1 #undef y0 #undef L1 #undef L0 #undef N #undef x #undef Ready #undef Start #undef pStart } //========================================= //=========== Демультиплексор ============= extern "C" __declspec(dllexport) int RDSCALL TestSW(int CallMode, RDS_PBLOCKDATA BlockData, LPVOID ExtParam) { // Макроопределения для статических переменных #define pStart ((char *)(BlockData->VarTreeData)) #define Start (*((char *)(pStart))) #define Ready (*((char *)(pStart+RDS_VSZ_S))) #define x (*((double *)(pStart+2*RDS_VSZ_S))) #define N (*((RDSINT32 *)(pStart+2*RDS_VSZ_S+RDS_VSZ_D))) #define pY ((void **)(pStart+2*RDS_VSZ_S+RDS_VSZ_D+RDS_VSZ_I)) switch(CallMode) { // Проверка типа переменных case RDS_BFM_VARCHECK: if(strcmp((char*)ExtParam,"{SSDIMD}")==0) return RDS_BFR_DONE; return RDS_BFR_BADVARSMSG; // Выполнение такта моделирования case RDS_BFM_MODEL: if(N<0) // Значение N не должно быть отрицательным Ready=0; // Не передавать ничего по связям else // Значение N не отрицательно { int count; double *array; // Число элементов в массиве Y count=RDS_ARRAYEXISTS(pY)?RDS_ARRAYCOLS(pY):0; if(N>=count) // Число элементов недостаточно { // Увеличение размера Y if(!rdsResizeVarArray(pY,1,N+1,TRUE,NULL)) { // Ошибка: не удалось увеличить размер массива rdsStopCalc(); // Остановка расчета // Не передавать ничего по связям Ready=0; // Вывод сообщения rdsMessageBoxW(L"Мало памяти", L"Ошибка", MB_OK | MB_ICONERROR); return RDS_BFR_DONE; } } // Получить указатель на первый элемент Y array=(double*)RDS_ARRAYDATA(pY); // Записать в Y[N] значение входа array[N]=x; } // else (N>=0) break; } return RDS_BFR_DONE; // Отмена макроопределений #undef pY #undef N #undef x #undef Ready #undef Start #undef pStart } //=========================================