Просмотр полной версии : Использование указателей Pointer
Андрей Плеханов
10.07.2013, 09:15
Добрый день. Интересует вопрос использования указателей (pointer of byte, word, dword). Моя конкретная ситуация "сохранение данных в переменную при чтении данных с модбас модулей". В модуле чтения UniRead мы задаём указатель на переменную куда будут читаться Pointer_of_byte. В моём случае на картинке-вложении ниже это переменная Ptr_Byte_Pozhar.
И так вопрос: Каким образом, используя какую библиотеку или функциональные модули мы записываем данные в глобальную переменную, имея Pointer?
9227
Андрей Плеханов
10.07.2013, 13:39
Подскажите пожалуйста библиотеку c элементами для перекладывания данных в переменную с помощью указателя, используя pointer_of_byte/word/dword
язык LD
Используйте оператор ^ для разыменования указателя (для обращения к переменной под указателем). Byte_Pozhar2 := Ptr_Byte_Pozhar^, например.
Андрей Плеханов
15.07.2013, 06:23
спасибо за помощь
Андрей Плеханов
15.07.2013, 11:11
Используйте оператор ^ для разыменования указателя (для обращения к переменной под указателем). Byte_Pozhar2 := Ptr_Byte_Pozhar^, например.
А если необходимо наоборот присвоить указателю адрес байта, то получается Ptr_Byte_Pozhar^ := Byte_Pozhar2
так правильно будет?
Андрей Плеханов
15.07.2013, 11:31
Используйте оператор ^ для разыменования указателя (для обращения к переменной под указателем). Byte_Pozhar2 := Ptr_Byte_Pozhar^, например.
После создания функционального блока с подобным скриптом при попытке запуска в онлайн режиме (эмуляция) - Индикация "Программа загружена - ИСКЛЮЧЕНИЕ" Подскажите в чём может быть проблема?
9284
Андрей Плеханов
15.07.2013, 14:25
разобрался
Подскажите где про указатели инфу найти можно, а то я так и не пойму как с ними работать.
Mikhail Shvetsov
04.12.2013, 11:33
Подскажите где про указатели инфу найти можно, а то я так и не пойму как с ними работать.
http://ru.wikipedia.org/wiki/Указатель_(тип_данных)
Все тоже самое для любых языков ( кроме тех, где от указателей отказались принципиально)
Отдельного руководства по использованию указателей в CODESYS я не встречал, да оно и не особо нужно. Главное понять принцип работы с ним, а это можно по вышеприведенной ссылке.
Основное понятие: Указатель - это адрес ячейки памяти, одного байта, не зависимо от типа содержания в той ячейки.
Чтобы прописать или считать данные по адресу нужно обратиться по этому адресу c ^.
пример:
PROGRAM PLC_PRG
VAR
pX : POINTER TO BYTE;
pY : POINTER TO INT;
x : BYTE;
y : INT;
END_VAR
/*---------------------------------*/
pX := ADR(x);
pY := ADR(y);
pX^ := 1;
pY^ := 123;
первые две строчки получают адреса переменных x и y и записывают их в соответствующие указатели.
Далее по этим адресам мы записываем данные, которые отобразятся в переменных x и y (потому как указатели указывают на них);
Повторюсь любой указатель указывает только на 1 байт. тип (to int к примеру) приписывается только для того, чтоб кодесис знал сколько байт от этого указателя и далее брать для операци с ^. Это дает удобство в работе с ними, но также кроется опасность.
К примеру код:
pY := adr(x); не является не корректным, в этом случае указатели pX и pY будут ссылаться на один и тот же байт, где лежит значение переменной x. Но операция pY^ := N использует первый байт (где x лежит) и затрет следующий байт за ним, потому, что pY это указатель на int, а int имеет размер 2x байтов, следовательно операция pY^ будет использовать 2 байта от указателя. Така не аккуратность приводит к параличу программы.
Указатели на кусок памяти удобно использовать во многих случаях. Один из - передача больших массивов данных из одной функции в другую:
arr: array[1..10000] of LWORD; - массив 8* 10000 байт
передача параметром его в фунцию:
someFunction(arr); - приведет к копированию всех 80 000 байт, что займет длительное время.
передача же указателя :
pArr : pointer to byte;
sizeOfArr : uint := 80000;
pArr := adr(arr);
someFunction(pArr, sizeOfArr); - копирует всего 4 байта самого указателя и 2 байта размера, и при этом функция получает доступ к массиву в 80 000 байт.
Это наиболее распространенный, но все же частный случай использования указателя был выделен в кодесис в отдельную группу переменных VAR_IN_OUT, что по сути является скрытым использованием указателей при передачи больших объемов данных между POU.
Спасибо за развернутый ответ! Будем изучать... А на СFС это как будет выглядеть?
Mikhail Shvetsov
04.12.2013, 15:40
некоторые ST операторы можно писать прям в блоках CFC к примеру [adr(x)]--[pX^] ;
а ниже пример где adr вынесен в отдельный блок
10965
Привет всем. Нуждаюсь в вашей помощи.
Каким образом мне в подпрограмме собрать ДИНАМИЧЕСКИ имя переменной. Например в PHP я могу слепить имя переменной из двух строк, а потом тому что получилось присвоить значение.
Например:
Я назвал физический выход контроллера как DigitalOut1
13722
Потом в подпрограмму я отправляю две строки. Первая -DigitalOut, вторая - 1.
В подпрограмме я склеиваю эти строки
VarSTRING := CONCAT ('DigitalOut','1');
и в переменной VarSTRING, я получил строку - DigitalOut1.
Как в данном случае, после склеивания мне задать DigitalOut1:=true; ?
Знаю что копать нужно в сторону pointer, но что то не получается....
Привет всем. Нуждаюсь в вашей помощи.
Каким образом мне в подпрограмме собрать ДИНАМИЧЕСКИ имя переменной. Например в PHP я могу слепить имя переменной из двух строк, а потом тому что получилось присвоить значение.
Например:
Я назвал физический выход контроллера как DigitalOut1
13722
Потом в подпрограмму я отправляю две строки. Первая -DigitalOut, вторая - 1.
В подпрограмме я склеиваю эти строки
VarSTRING := CONCAT ('DigitalOut','1');
и в переменной VarSTRING, я получил строку - DigitalOut1.
Как в данном случае, после склеивания мне задать DigitalOut1:=true; ?
Знаю что копать нужно в сторону pointer, но что то не получается....
Указатели Вам не помогут
Указатели Вам не помогут
А варианты реализации вообще есть?
А варианты реализации вообще есть?
обзываете начальный адрес памяти определенным именем и далее используя указатель перемещяетесь по памяти на столько байт, сколько лежит между переменными либо структуры, либо ПОУ либо конфигурации
обзываете начальный адрес памяти определенным именем и далее используя указатель перемещяетесь по памяти на столько байт, сколько лежит между переменными либо структуры, либо ПОУ либо конфигурации
Взорвали мозг. Где в мануалах это можно увидеть? Или примеры...
Никогда с этим не сталкивался...
там вообще все просто, из примеров: нужна конкретная задача, тогда и примеры кто нить выложит. А так по минимуму http://www.owen.ru/forum/showthread.php?t=15548&p=122956&viewfull=1#post122956
Спасибо, но если у вас есть время, хотелось бы поговорить подробнее...)
из примера:
sPnt:=ADR(slv); - slv - мои данные. Здесь я получил адрес где мои данные лежат. (Правильно понял?)
sz := SIZEOF(sPnt^); - размер моих данных.
Попробовал. Ни чего не понял... Простите...
13724
Спасибо! С ADR разобрался.
13728
Но данным образом я обращаюсь ко всем 16ти выходам. Конечно можно выдергивать их по отдельности типо первый выход мне нужно выставить 1, второй - 2, третий - 4, и т.д...
Но это не очень удобно.
А явно к %QX0.5 мне ни как нельзя обратиться?
Вы бы задачу описали бы подробнее, может есть более простое решение.
Lode Runner
24.07.2014, 06:58
Организуйте упаковку этой переменной из булей, в цикле или стандартной функцией, как нравится.
Обращаться напрямую к физической МЭК-адресации я бы не рекомендовал, будут проблемы с портируемостью и читаемостью кода. А в третьей редакции стандарта и нельзя, насколько я знаю.
Спасибо! С ADR разобрался.
13728
Но данным образом я обращаюсь ко всем 16ти выходам. Конечно можно выдергивать их по отдельности типо первый выход мне нужно выставить 1, второй - 2, третий - 4, и т.д...
Но это не очень удобно.
А явно к %QX0.5 мне ни как нельзя обратиться?
Если правильно понял можно поступить как во вложении
Спасибо, буду разбираться с кодом.
С задачей чуть по позже.
Кхе,че там разбираться то,есть один только момент,он упомянут в описании bitadr, чтоб была отключена байт-адресация, собственно проект должен это оставить как надо, можно вообще пропустить получение смещения, просто иметь начальную переменную и в каждом байте на который ссылается указатель, менять соответствующие биты
Powered by vBulletin® Version 4.2.3 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot