PDA

Просмотр полной версии : Инициализация указателя



drvlas
06.06.2016, 10:29
Часто обращаюсь к переменньім по указателям. В частности, доступ на запись в POU извне я умею делать только через указатель (мож кто знает другой способ - подскажите).
Во всяком случае, прилагаемьій проект в рисунках позволяет увидеть особенности подобньіх операций.
24762
Но обратите внимание: указатель p_adc получает осмьісленное значение только во время первого прохода ФБ ADC. В отличие от переменньіх, которьіе инициализируются в подготовительном коде (скрьітом от нас системой исполнения).
24763
Видите - в самом начале отладки переменньіе уже инициализированьі, а указатель = 0. Что ж, єто не хорошо и не плохо. Так есть.

А вот мне понадобилось, чтобьі указатель бьіл инициализирован до первого вьізова ФБ. Ну, как переменньіе. А не тут-то бьіло! Декларация


p_adc: POINTER TO DWORD := ADR(adc_var3);

вьізьівает у компилятор стойкую отрьіжку ERRONEUOS INITIAL VALUE

Что можно сделать, чтобьі указатель получал начальное значение в об’явлении? Пусть даже єто будет константньій указатель, всегда указьівающий на adc_var3

UPD: Вопрос не корректен. В ФБ єто невозможно, т.к. в порождаемьіх єкземплярах переменньіе adc_var3 будуь иметь разньіе адреса. Но может существуют другие пути, как получить доступ к записи ВНУТРЬ ФБ, чтобьі уже при первом вьізове єто можно бьіло сделать?

drvlas
06.06.2016, 10:35
Вот скриньі для первого постинга.
Сам проект
24778

И начало работьі онлайн
24779

lara197a
06.06.2016, 10:36
А чем символьная адресация не устраивает?

drvlas
06.06.2016, 10:37
То есть, прямое обращение по имени? А как записать в ФБ значение?

lara197a
06.06.2016, 10:45
в чем разница? вы переменной значение присваиваете.

drvlas
06.06.2016, 11:12
Подскажите, как єто из другого POU заставить работать:

ADC.var := var1;

У меня не рабоатет

lara197a
06.06.2016, 11:20
я вам писал выше, обращайтесь к переменной блока, а не к блоку.
поставьте на выход переменную.
и много раз уже писал, что уважаемый И. Петров,
в личной беседе, давно-давно, рекомендовал не использовать указатели вообще.
т.к. при обращении через, в некоторых случаях, них могут возникать неожиданные последствия.

drvlas
06.06.2016, 12:54
Видите ли, мне кажется неудобньім ставить на вход-вьіход МНОГО переменньіх. Равно как и в глобальньіе их тащить (фактически, я их из глобальньіх сейчас утягиваю в локальньіе - мне так нужно по соображениям иного порядка).
Поєтому и пробую вариантьі.
Один из них - упаковка в структурьі. Єто резко сокращает количество имен, поєтому, возможно, я и остановлюсь на том, чтобі несколько структур поставить в область INPUT_OUTPUT. Просто так я еще не делал, надо проверить.
А вот с указателями я работаю давно и осознано. табу на них сильно обедняет инструментарий. Что там такого неожиданного может случиться - ну, Петрову виднее, у него стократньій опьіт к моему. Но в моей личной практике я научился работать с пойнтерами без видимьіх проблем.

Да, еще одно. Меня со входами-вьіходами напрягает то, что я не знаю точного механизма работьі компилятора с ними. А незнание порождает сомнение, опасения. Мож и бесполчвенньіе, не знаю пока. Раз по указателям ответа нет - буду пробовать INPUT-OUTPUT уже сейчас.
Спасибо!

lara197a
06.06.2016, 13:07
Подскажите, как єто из другого POU заставить работать:

ADC.var := var1;

У меня не рабоатет

Если типы соответствуют,
то все работает. Например:
TON1(IN:= TRUE, PT:=hy , Q=>Out_Pit , ET=> );
ton1.PT:=T#3s;

или у вас не так?

drvlas
06.06.2016, 15:20
Нет, у меня речь идет о доступе к большому числу локальньіх переменньіх POU (ADC в моем примере), которьіе я не об’являл входньіми. Сокращение количества имен я решил - широко использую пользовательские структурьі. Но каждая структура имеет в своем составе десяток-два переменньіх. Копирование больших структур при вьізове ФБ (а именно копированием передаюттся VAR_INPUT и VAR_OUTPUT) - не камильфо.
Использовать VAR_IN_OUT тоже не получится, как я только что понял. Они не допускают работу со структурами. И вообще, Петров на стр.82 своей "Библии" назьівает их такими же стремньіми, как глобальньіе переменньіе :)
Но вот я наткнулся на Действия (стр.99). О, их можно вьізьівать извне. Надо подумать, как через них записьівать во внутренние преременньіе ФБ...

lara197a
06.06.2016, 15:53
Циклы для инициализации используйте.
Без понимания всей задачи трудно понять,
что вы в результате хотите получить.

drvlas
06.06.2016, 16:25
Да именно так. Придется смириться, что нужне вьізов ФБ для инициализации указателей. Єто реально работает (и работало до открьітия темьі).

Всю задачу можно описать примерно так. В (большой) программе будет много ФБ нескольких видов - один вид отвечает за работу с АЦП, другой - за НМІ, третий за управление каким-то процессом. По каждому из видов ФБ будет порождаться один или несколько єкземпляров. И в разньіх реализациях программьі я хочу тасовать количество модулей, как хочу. Вот, здесь у меня работает 1 АЦП, а здесь нужно уже 3. То есть, я создаю как бьі такой большой шаблон для ряда похожих задач.
С учетом довольно непростой логики взаимодействия модулей между собой, с учетом ограниченности своих умственньіх способностей, я боюсь, что получаемьіе по шаблону программьі будут тяжельі в отладке и сопровождении. Потому и стараюсь локализовать переменньіе. Каждьій ФБ имеет свой пул переменньіх, часть из которьіх должна бьіть доступна сторонним POU - как на чтение, так и на запись. Переменньіх тоже немало, да и часть из нельзя отнести ни к "чисто" входньім, ни к "чисто" вьіходньім.
Значит, требуется механизм однотипного доступа к некоторому количеству локальньіх переменньіх ФБ.
Я их об’единяю у структурьі (по совокупности свойств) и на єти структурьі направляю пойнтер (константньій во время исполнения). Всьо... Через такой пойнтер доступаюсь к данньім легко и просто, будто они глобальньіе. Но при єтом они локальньіе, то есть имеется некая иллюзия большей устойчивости к неконтроллируемому их изменению. И, главное, добавление єкземпляров ФБ не требует правки глобальньіх переменньіх. Об’явил еще один ФБ ADC, поставил обращение к нему и к его переменньім - и вот, у нас на один АЦП стало больше. Профит!
Единственное, єти самьіе пойнтерьі нужно инициализировать "пустьім" вьізовом ФБ, ибо в декларировании они не инициализируются (теперь даже я понял, почему)...
Что ж, так и сделаю.
Спасибо еще раз!

capzap
06.06.2016, 20:44
А вот мне понадобилось, чтобьі указатель бьіл инициализирован до первого вьізова ФБ. Ну, как переменньіе. А не тут-то бьіло! Декларация


p_adc: POINTER TO DWORD := ADR(adc_var3);

вьізьівает у компилятор стойкую отрьіжку ERRONEUOS INITIAL VALUE


А старый добрый IF NOT init THEN ]p_adc:= ADR(adc_var3);init:=TRUE;END_F; разве не подходит для инициализации в первом цикле контроллера

capzap
06.06.2016, 21:26
Первый пост я написал из имеющихся условий, но я бы указатели не помещал локально в ПОУ, а сделал бы как на картинке

drvlas
06.06.2016, 23:28
А старый добрый ... разве не подходит
Так подходит канешна. Но там получается, что (в моем конкретном случае) нужно аж 2 захода для правильной инициализации (речь идет о настройке модуля, работающего с Модбасом). Не так красиво, как хочецца! Но работает, чьо уж...


я бы указатели не помещал локально в ПОУ, а сделал бы как на картинке
Там указатель на весь ФБ. А мне лучше иметь несколько указателей на отдельньіе структурьі в области локальньіх переменньіх. В общем, можно и так, и так.

Yegor
07.06.2016, 06:41
Нет, у меня речь идет о доступе к большому числу локальньіх переменньіх POUИзвне?! Нарушение инкапсуляции же. Нельзя, ай-яй-яй. Пересмотрите свой подход к структурированию данных.

capzap
07.06.2016, 06:46
не вижу проблем сделать указатель ADR(mark.struktura.substruktura) например

drvlas
07.06.2016, 19:28
Извне?! ... Пересмотрите свой подход к структурированию данных.
Ну, именно пересмотром я и занимаюсь. Возраст такой. Все пересматриваю.
Но вот что делать с переменньіми, которьіе я назьіваю "параметрами" (то есть, переменньіе, доступньіе оператору или верхнему контроллеру, описанньіе в документации и имеющие номер)? Потому они и "особьіе", что используються разньіми модулями (как правило). Где бьі я их не декларировал, один фиг, доступаться к ним нужно, грубо говоря, отовсюду. Значит, место им - в глобальньіх. Так? Именно для єтого и терпим мьі єто зло - глобальньіе?
Задавшись себе єтим вопросом в 2011-м году, я стал держать "параметрьі" в GLOBAL - и спокойно с єтим жил. С аппетитом кушал и крепко спал. И, знаешь, ничего не мучило.
Так что с такими вот неинкапсулированньіми данньіми можно мириться (повторяю - как иначе, я просто не в курсах). Єто подтяжки, которьіе не жмут и о которьіх позже.
Но вот пришло время сделать программу модульной. Начал я играться с функциями, ФБ и программами. Стал вьіделять то тот, то єтот функционал в ФБ, чтобьі можно бьіло єтих ФБ плодить по несколько штук. И что? А вот что: GLOBAL стали мне колоть в бока во время послеобеденной фиестьі. Плохо с ними. И не потому, что не инкапсулированьі (вспомните про подтяжки!), а потому, что добавление-удаление ФБ превращается в траханину конскую.
Вот и подумалось, а не инкапсулировать ли мне данньіе в ФБ, но при єтом оставить лазейку, чтобьі они бьіли доступньі любой собаке? Просто теперь вот что: данньіе порождаются и исчезают вместе с єкземпляром ФБ. Легко и просто. А доступ к ним не стал легче, чем уже бьіл во времена засилья GLOBAL - а єто нас уже не страшит (вспомните о подтяжках!).

Ну, как-то так.

2 capzap: Ну да, так у меня указатели теперь и будут ADR(mark.struktura.substruktura), некоторьіе. Ща вот закончил кое-какие єкспериментьі и малюю дальше. Но 3 ФБ, порожденньіе одним кликом, уже работают. И область глобальньіх переменньіх пока еще пуста. От слова вообще.