Нарушение прав доступа Когда Form2 пытается отредактировать form1 В delphi

Например, когда я пытаюсь сделать что-то вроде этого

form2.Edit1.text=form1.edit1.text

Выдает ошибку нарушения прав доступа.

Способ, которым form2 может использовать переменные form1, заключается в добавлении

uses Unit1; var Form1:Tform1

реализации

Программа компилируется нормально, без ошибок, но при попытке доступа к edit1 из form1 происходит сбой с ошибкой.

редактировать:

Похоже, он работает, когда я добавляю unit1 в список «использует» не в реализации, а в интерфейсе

что означает, что unit2 может редактировать unit1, но теперь я не могу добавить unit2 к использованию интерфейса круговой ссылки на unit1

Короче говоря, это означало

  • блок2 может редактировать/просматривать блок1
  • unit1 не может редактировать/просматривать unit2

Итак, есть ли способ сделать это возможным без создания третьего кадра, на который ссылаются два других блока?


person Evyatar    schedule 07.02.2012    source источник
comment
Похоже, это работает, когда я добавляю unit1 в список использования не в реализации, а в интерфейсе, что означает, что unit2 может редактировать unit1, но я не могу теперь добавить unit2 к использованию интерфейса unit1. Короче говоря, это означало - unit2 может редактировать/просматривать unit1 - unit1 не может редактировать/просматривать unit2 Итак, есть ли способ сделать это возможным?   -  person Evyatar    schedule 07.02.2012
comment
Как указал Ноам Ньюман, убедитесь, что вы не переопределяете переменную Form1. Кроме того, проверьте в Project->Options->Forms, если у вас есть Form1 и Form2 в списке автоматически создаваемых форм.   -  person Wodzu    schedule 07.02.2012


Ответы (5)


В вашем проекте есть две переменные с именем Form1. Код в файле .dpr создает TForm1 и сохраняет ссылку в одной из двух переменных Form1. Затем вы имеете в виду другой неназначенный Form1.

Это объясняет, почему вы получаете нарушение доступа. Как это исправить? Просто удалите переменную Form1 из Unit2. Используйте функцию «Найти в файлах», чтобы убедиться, что у вас есть только одно объявление Form1, Form2 и т. д. во всем проекте.

Когда вы сделаете это правильно, у вас не будет проблем с тем, чтобы каждый модуль использовал другой, из раздела реализации, без проблем с циклическими ссылками.

Чтобы лучше изучить и понять это, я предлагаю вам прочитать файл .dpr, чтобы понять, как инициализируются глобальные переменные. Я также рекомендую вам прочитать раздел руководства по языку Delphi, посвященный разрешению области видимости, чтобы понять, как компилятор разрешает ситуации, когда два одинаковых имени видны в одном и том же месте.

person David Heffernan    schedule 07.02.2012
comment
Соглашаться. Лично я редко позволяю .dpr инициализировать любые другие формы, кроме основной формы приложения. Другие формы я инициализирую вручную всякий раз, когда они нужны. Кроме того, я думаю, что хорошей практикой является не хранить переменные формы как глобальные переменные, а сохранять их как переменные-члены других форм, из которых они используются. - person bjaastad_e; 08.02.2012
comment
@Elling Я согласен с этим и делаю то же самое. Однако при объяснении таких вещей начинающему программисту лучше делать небольшие шаги. - person David Heffernan; 08.02.2012

Нет необходимости объявлять form1 как переменную в form2 — будет глобальная переменная с именем form1.

person No'am Newman    schedule 07.02.2012
comment
@HTxL: откуда именно вы вызываете код? Либо указатель Form1, либо Form2 недействителен в этом контексте. Пожалуйста, покажите более полный фрагмент кода, который показывает, что вы на самом деле делаете. - person Remy Lebeau; 07.02.2012
comment
@HTxL: где создается экземпляр form1? Если это не основная форма, вам нужно убедиться, что она создана, прежде чем Form2 будет использовать ее во время выполнения. - person Marjan Venema; 07.02.2012

Поставил Unit1 под реализацию, использует в Unit2. Не объявляйте Form1 в Unit2. Если вы объявите Form1 в Unit2 и не присвоите ему значение, это будет нулевой указатель, дающий нарушение доступа при доступе. Если вы освободили форму Form1 или не создали ее, это также приведет к нарушению прав доступа.

person MGH    schedule 07.02.2012

Тот факт, что ваш проект компилируется, означает, что переменная "Form2" объявлена и, таким образом, "известна" компилятору. Тот факт, что это дает нарушение доступа, означает, что этой переменной не назначен допустимый объект. Есть несколько возможностей. Во-первых, Form2 должен быть создан с помощью IDE (автоматически создать форму в настройках проекта) или с помощью вашего кода. Во-вторых, не должно быть второй переменной с именем «Form2», которая «скрывает» переменную с объектом Form2.

Вы можете и должны избегать циклических ссылок в предложениях use. Используйте их в разделе «интерфейс», если это возможно. Конечно, вы можете ссылаться более чем на две единицы...

person Andreas    schedule 07.02.2012
comment
использовать их в разделе реализация, если это возможно? - person MGH; 07.02.2012
comment
@MGH: Или: в разделе интерфейса, если возможно, в разделе реализации, если необходимо - person Marjan Venema; 07.02.2012
comment
@Marjan, Андреас, я не думаю, что это правильно. Если я заставлю два модуля использовать друг друга в разделе интерфейса, будет создана циклическая ссылка. Если они используют друг друга через раздел реализации, это работает. - person MGH; 08.02.2012
comment
@MGH: Мы упомянули, что обычно у меня есть все в разделе использования раздела интерфейса, а в разделе использования раздела реализации я помещаю только единицы, чтобы избежать циклической ссылки. Означает, что вы никогда не создаете циклическую ссылку, не узнав об этом от компилятора. - person Marjan Venema; 08.02.2012

Правильным ответом для меня было добавление модуля1 к интерфейсу модуля2 и добавление модуля2 к реализации модуля1.

Это связано с тем, что блок1 является основной формой, а блок2 открывается блоком1. поэтому добавление unit1 к реализации unit2 не сработает. Это сработало бы, если бы оба блока были открыты вместе.

person Evyatar    schedule 07.02.2012
comment
Разве это не то же самое, что ответил Андреас? - person EMBarbosa; 07.02.2012