Перейти к содержанию
Fire Monkey от А до Я
  • 0

Детский вопрос про область видимости переменной


Вопрос

Неловко спрашивать о таком на третьем десятке лет программирования на Delphi, но всё же спрошу. Вот предельно простой код:

program MyProgram;

uses
  MyUnit in 'MyUnit.pas' {MyForm};

var MyVariable: Boolean=False;

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TMyForm, MyForm);
  Application.Run;
end.

Как мне обратиться к переменной MyVariable из юнита MyUnit?

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

Вынеси эту переменную в отдельный модуль 'MyVariableUnit.pas' и добавь его во все места, где нужно обращаться к переменной

Ссылка на комментарий
  • 0
30 минут назад, rareMax сказал:

Вынеси эту переменную в отдельный модуль 'MyVariableUnit.pas' и добавь его во все места, где нужно обращаться к переменной

Неужели нет более простого решения?

Ссылка на комментарий
  • 0
unit SharedGlobals;

interface

const
  ConstMyConstant = 30;

type
  TMyType = record
    AValue : String;
  end;

var
  MyVariable: Boolean=False;

  function MyFunction(AValue : String) : String;

implementation

function MyFunction(AValue : String) : String;
begin

end;

end.

И использование этого:

unit Unit1;

interface

uses
  SharedGlobals,
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    АMyType : TMyType;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormCreate(Sender: TObject);
begin
  АMyType.AValue:=ConstMyConstant;
  MyFunction(АMyType.AValue);
end;

end.

 

Ссылка на комментарий
  • 0
15 часов назад, Вадим Смоленский сказал:

Выходит, только так, а напрямую нельзя.

Вы бы раскрыли смысл своего вопроса такого обращения к переменной, тогда может кто-то и подскажет решение.

Ссылка на комментарий
  • 0
4 часа назад, GASCHE сказал:

Вы бы раскрыли смысл своего вопроса такого обращения к переменной, тогда может кто-то и подскажет решение.

Специального смысла нет. Я просто был уверен, что существует некий способ такого обращения, и мне было досадно, что я его не знаю. В практическом же плане меня вполне устроит и подсказанный способ - тем более, что юнит с глобально используемыми процедурами в моем проекте уже есть, мне просто не пришло в голову разместить там же глобальные переменные.

Ссылка на комментарий
  • 0

Обычно я делаю класс TCore, в котором все необходимое и настройки и переменные, я стараюсь формы и логику всегда отделять (раньше для Windows я вообще отделял логику и ядро в DLL ). Формы нужны только для отображения содержимого. Этот класс создаю в dpr до всех форм, Core соответсвенно в отдельном модуле, и глобальная переменная gCore там же в interface. Этот Core.pas подключаю уже везде. Это очень практично.

Изменено пользователем ENERGY
Ссылка на комментарий
  • 0

Существует (если нельзя, но очень хочется, то можно). Правда проверял его работоспособность в VCL, в FM проверьте сами.

program Project2;

uses
  Vcl.Forms,
  Unit1 in 'Unit1.pas' {Form1};

var
  MyVariableInt: Integer;
  MyVariableBool: Boolean;
  MyVariableStr: string;

exports
  MyVariableInt,
  MyVariableBool,
  MyVariableStr;

{$R *.res}

begin
  MyVariableInt := 456;
  MyVariableBool := True;
  MyVariableStr := 'qwerty'#0;

  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  i: ^Integer;
begin
   i := GetProcAddress(HInstance, 'MyVariableInt');
   if Assigned(i) then
      ShowMessage(IntToStr(i^));

   i := GetProcAddress(HInstance, 'MyVariableBool');
   if Assigned(i) then
      ShowMessage(BoolToStr(Boolean(i^)));

   i := GetProcAddress(HInstance, 'MyVariableStr');
   if Assigned(i) then
      ShowMessage(PChar(i^));
end;

end.

 

Ссылка на комментарий
  • 0

@estra Так лучше не делать, т.к. решение не кроссплатформенное.  Не пойму что мешает автору завести отдельный pas модуль, например GlobalConst.pas и там объявить эту глобальную переменную и затем подключать этот модуль куда угодно. Это надуманная проблема. 

Ссылка на комментарий
  • 0
30 минут назад, ENERGY сказал:

@estra Так лучше не делать, т.к. решение не кроссплатформенное.  Не пойму что мешает автору завести отдельный pas модуль, например GlobalConst.pas и там объявить эту глобальную переменную и затем подключать этот модуль куда угодно. Это надуманная проблема. 

А я могу понять автора, хотя и с оговоркой.

Вы правы, способ не кроссплатформенный, но мы и не знаем, под какую ОС пишет ТС. Если под Винду, то почему бы и нет. Если нужно кроссплатформенное решение, то GlobalConst.pas  прекрасно подойдет, никто не спорит.

Но, подобными вопросами полезно задаваться и решать их в познавательных и исследовательских целях, чтобы лучше узнать инструмент, который используешь в работе. ТС не знал такого способа, теперь узнает, прокачает свои скилы, разве ж это плохо)))

Да и даже чисто с практической точки зрения, бывают задачи, которые просто невозможно решить, не прибегая к хакам. Так что знать о них нужно, но применять с умом и осторожностью, ибо они не панацея!!!

Изменено пользователем estra
Ссылка на комментарий
  • 0
2 часа назад, estra сказал:

в FM проверьте сами

Проверил, в FMX под Windows  не работает. После выполнения GetProcAddress отладчик показывает, что i=nil.

Да и бог с ним, что не работает. Я вижу, что тривиального решения нет - именно это и хотел узнать. А способ с отдельным юнитом меня вполне устраивает.

Изменено пользователем Вадим Смоленский
Ссылка на комментарий
  • 0
4 минуты назад, Вадим Смоленский сказал:

Проверил, не работает. После выполнения GetProcAddress отладчик показывает, что i=nil.

Да и бог с ним, что не работает. Я вижу, что тривиального решения нет - именно это и хотел узнать. А способ с отдельным юнитом меня вполне устраивает.

Значит не под Windows проверяли, ибо у меня под винду все работает...

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...