Полный исходный текст на языке C++ для библиотеки (DLL) с моделями блоков, организующих передачу матрицы вещественных чисел между частями схемы через динамическую переменную «DynMatr». Библиотека содержит две модели:
- TestDynMatrCreate – блок-передатчик;
- TestDynMatrGet – блок-приемник.
// Передача матрицы через динамическую переменную #include <windows.h> #include <math.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 TestDynMatrCreate(int CallMode, RDS_PBLOCKDATA BlockData, LPVOID ExtParam) { // Макроопределения для статических переменных #define pStart ((char *)(BlockData->VarTreeData)) #define Start (*((char *)(pStart))) #define Ready (*((char *)(pStart+RDS_VSZ_S))) #define pX ((void **)(pStart+2*RDS_VSZ_S)) // Вспомогательная переменная – указатель на структуру подписки RDS_PDYNVARLINK Link; switch(CallMode) { // Инициализация блока case RDS_BFM_INIT: // Создание динамической переменной Link=rdsCreateAndSubscribeDV(RDS_DVROOT, // В корневой "DynMatr", // Имя переменной "MD", // Тип TRUE, // Запрет удаления NULL); // Без нач.знач. // Запомнить указатель на структуру подписки BlockData->BlockData=Link; break; // Очистка case RDS_BFM_CLEANUP: // Запомненный указатель на структуру подписки Link=(RDS_PDYNVARLINK)BlockData->BlockData; // Удалить переменную rdsDeleteDVByLink(Link); break; // Проверка типа статических переменных case RDS_BFM_VARCHECK: if(strcmp((char*)ExtParam,"{SSMD}")==0) return RDS_BFR_DONE; return RDS_BFR_BADVARSMSG; // Такт расчета case RDS_BFM_MODEL: // Запомненный указатель на структуру подписки Link=(RDS_PDYNVARLINK)BlockData->BlockData; // Если переменная существует, копировать входную матрицу // в матрицу динамической переменной if(Link!=NULL && Link->Data!=NULL) { // Копирование X в динамическую переменную rdsCopyVarArray(Link->Data,pX); // Уведомление подписчиков rdsNotifyDynVarSubscribers(Link); } break; } return RDS_BFR_DONE; // Отмена макроопределений #undef pX #undef Ready #undef Start #undef pStart } //========================================= //============ Блок-приемник ============== extern "C" __declspec(dllexport) int RDSCALL TestDynMatrGet(int CallMode, RDS_PBLOCKDATA BlockData, LPVOID ExtParam) { // Макроопределения для статических переменных #define pStart ((char *)(BlockData->VarTreeData)) #define Start (*((char *)(pStart))) #define Ready (*((char *)(pStart+RDS_VSZ_S))) #define pY ((void **)(pStart+2*RDS_VSZ_S)) #define s (*((double *)(pStart+2*RDS_VSZ_S+RDS_VSZ_M))) // Вспомогательная переменная – указатель на структуру подписки RDS_PDYNVARLINK Link; switch(CallMode) { // Инициализация блока case RDS_BFM_INIT: // Подписка на динамическую переменную Link=rdsSubscribeToDynamicVar(RDS_DVROOT, // В корневой "DynMatr", // Имя "MD", // Тип FALSE); // Без поиска // Запомнить указатель на структуру подписки BlockData->BlockData=Link; break; // Очистка case RDS_BFM_CLEANUP: // Запомненный указатель на структуру подписки Link=(RDS_PDYNVARLINK)BlockData->BlockData; // Прекратить подписку rdsUnsubscribeFromDynamicVar(Link); break; // Проверка типа статических переменных case RDS_BFM_VARCHECK: if(strcmp((char*)ExtParam,"{SSMDD}")==0) return RDS_BFR_DONE; return RDS_BFR_BADVARSMSG; // Изменение динамической переменой или такт расчета case RDS_BFM_DYNVARCHANGE: case RDS_BFM_MODEL: // Запомненный указатель на структуру подписки Link=(RDS_PDYNVARLINK)BlockData->BlockData; // В s будут суммироваться элементы матрицы s=0; // Проверка существования динамической переменной if(Link!=NULL && Link->Data!=NULL) { // Копировать динамическую матрицу в Y rdsCopyVarArray(pY,Link->Data); // Если матрица не нулевого размера – суммировать if(RDS_ARRAYEXISTS(Link->Data)) { // Число элементов в матрице int count=RDS_ARRAYROWS(Link->Data)* RDS_ARRAYCOLS(Link->Data); // Указатель на начало данных матрицы double *data=(double*)RDS_ARRAYDATA(Link->Data); // Суммирование элементов в цикле for(int i=0;i<count;i++) s+=data[i]; } // Взвести Ready для передачи выходов по связям Ready=1; } break; } return RDS_BFR_DONE; // Отмена макроопределений #undef s #undef pY #undef Ready #undef Start #undef pStart } //=========================================