powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Освободить из основной программы класс объявленный в коде FastScript
5 сообщений из 5, страница 1 из 1
Освободить из основной программы класс объявленный в коде FastScript
    #40058526
vdix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Имплементировал в серверном приложение FastScript, одна из функций должна возвращать структуру, но в виду того, что record не поддерживается фастскриптом, приходится создавать класс. Будь это клиентское приложение, особой проблемы не возникло бы, но на сервере обнаружилась неприятная ситуация: утечка памяти. Класс, созданный в коде FastScript, не освобождается, потому что является результатом функции фастскрипта, а передаётся он в код основной программы сервера.

Код в фастскрипте выглядит примерно так:
Код: pascal
1.
2.
3.
4.
5.
6.
function OnCheckRequest(ParamIn: variant): TMyRequestResponse;
begin
  Result := TMyRequestResponse.Create;
  Result.ParamOut1 := 'something';
  Result.ParamOut2 := True;
end;


Что я попытался реализовать в коде самого серверного приложения:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
/// вызываю функцию фастскрипта и получаю результат в Х виде класса TMyRequestResponse
X := TMyRequestResponse(IntegerAScript.CallFunction1(fsScript, 'OnCheckRequest', ParamsVA)));
try
/// обработка результата всякое
/// ...

/// попытался найти и освободить инициализированную переменную класса TMyRequestResponse, но безуспешно:
{
    for I := 0 to Pred(fsScript.Count) do
    begin
      V := fsScript.Items[I];
      if V is TfsClassVariable then
        if TfsClassVariable(V).ClassRef.ClassName = 'TMyRequestResponse' then
        begin
          //if Integer(TfsClassVariable(V).ClassRef) = Integer(X) then // это никогда не происходит, видимо, в код Делфы передаётся копия класса, а не референс
          begin
            TfsClassVariable(V).Free;
            fsScript.Remove(V); // это сделать можно, но чуть попозже получим ошибку List index out of bounds. если не освобождать переменную строчкой выше - результат тот же
          end;
        end;
    end;
}
/// освобождаю локальную переменную, но утечку памяти это не исправляет
finally
  FreeAndNil(X);
end;


Если кто может предложить правильный вариант или альтернативное решение - буду весьма благодарен.
З.Ы. Возвращать результат через глобальную переменную/объект фастскрипта - не вариант, сервер работает в асинхронном режиме.
...
Рейтинг: 0 / 0
Освободить из основной программы класс объявленный в коде FastScript
    #40058582
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тестовый пример, который проходит (у меня) без утечек
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
type
TMyObject = class(TComponent)
  private
    fParam: variant;
    procedure DoEvent;
  published
    property Param: Variant read fParam write fParam;
end;

TFunctions = class(TfsRTTIModule)
  constructor Create(AScript: TfsScript); override;
end;

{ TFunctions }

constructor TFunctions.Create(AScript: TfsScript);
begin
  inherited;
  AScript.AddClass(TMyObject,'TComponent')
end;

procedure TForm1.Button1Click(Sender: TObject);
var X: TMyObject;
    ParamsVA: Variant;
begin
  ParamsVA := VarArrayCreate([0,0],varVariant);
  ParamsVA[0] := 'Test';
  fsScript1.Lines.Clear;
  fsScript1.Lines.Add('function OnCheckRequest(ParamIn: variant): TMyObject;');
  fsScript1.Lines.Add('begin');
  fsScript1.Lines.Add('  Result := TMyObject.Create(nil);');
  fsScript1.Lines.Add('  Result.Param := ParamIn;');
  fsScript1.Lines.Add('end;');
  fsScript1.Lines.Add('begin');
  fsScript1.Lines.Add('end.');
  fsScript1.AddRTTI;
  fsScript1.Compile;
  X := TMyObject(integer(fsScript1.CallFunction1('OnCheckRequest', ParamsVA)));
  try
    X.DoEvent();
  finally
    X.Free;
  end;
end;

{ TMyObject }

procedure TMyObject.DoEvent;
begin
  ShowMessage(Param);
end;

initialization
  fsRTTIModules.Add(TFunctions);

finalization
  fsRTTIModules.Remove(TFunctions);

end.

...
Рейтинг: 0 / 0
Освободить из основной программы класс объявленный в коде FastScript
    #40058587
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и появляется утечка, если добавить (и не уничтожить) ещё один объект.
...
Рейтинг: 0 / 0
Освободить из основной программы класс объявленный в коде FastScript
    #40058602
L_argo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Создайте процедуру для освобождения ресурса. Зарегистрируйте ее в ФР. Вызывайте ее в конце скрипта.
...
Рейтинг: 0 / 0
Освободить из основной программы класс объявленный в коде FastScript
    #40058622
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
За приведение к указателю через каст к integer еще не били кактусом по рукам?
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Освободить из основной программы класс объявленный в коде FastScript
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]