Как остановить эту утечку памяти Variant?

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

Это прекрасно работает для большинства вещей, но когда тип возвращаемого значения функции Delphi был Variant, возникает утечка памяти, потому что вариант никогда не удаляется. Кто-нибудь знает, как я могу взять нетипизированный параметр, содержащий вариант, и убедиться, что он будет правильно удален? Это, вероятно, потребует некоторой встроенной сборки.

procedure ConvertVariant(var input; var output: variant);
begin
  output := variant(input);
  asm
    //what do I put here? Input is still held in EAX at this point.
  end;
end;

РЕДАКТИРОВАТЬ: Отвечая на вопрос Роба Кеннеди в комментариях:

Преобразование AnsiString работает следующим образом:

procedure VarFromString2(var s : AnsiString; var v : Variant);
begin
  v := s;
  s := '';
end;

procedure StringToVar(var p; var v : Variant);
begin
  asm
    call VarFromString2
  end;
end;

Это работает нормально и не вызывает утечек памяти. Когда я пытаюсь сделать то же самое с вариантом в качестве входного параметра и назначаю исходный Null во второй процедуре, утечки памяти все еще происходят.

Варианты в основном содержат строки — рассматриваемый сценарий используется для генерации XML — и они получили это, назначив строку Delphi варианту в функции Delphi, которую вызывает этот сценарий. (В этом случае изменение типа возвращаемого значения функции не сработает.)


person Mason Wheeler    schedule 03.09.2010    source источник
comment
Как Variant изначально попал в этот первый параметр? Какой тип переменной использовался для фактического параметра? Когда вы говорите, что это работает для большинства вещей, включает ли это AnsiString? Утилизация этого должна быть аналогична утилизации Вариантов.   -  person Rob Kennedy    schedule 04.09.2010
comment
@Rob: Обновлено с ответами на ваши вопросы.   -  person Mason Wheeler    schedule 04.09.2010
comment
Я все еще хотел бы знать, как заполняется первый параметр. То есть, как вызываются ConvertVariant и StringToVar? Это это вариант в первом параметре, который утекает, верно?   -  person Rob Kennedy    schedule 04.09.2010
comment
Мейсон, ты пробовал использовать функцию varclear? docwiki.embarcadero.com/VCL/en/System.VarClear   -  person RRUZ    schedule 04.09.2010
comment
Я подозреваю, что ваша процедура StringToVar; может быть просто: asm jmp VarFromString2 end;.   -  person PhiS    schedule 06.09.2010


Ответы (1)


Пробовали ли вы тот же трюк, что и со строкой, за исключением того, что с Variant вы должны поставить UnAssigned вместо Null, чтобы освободить его, как вы сделали s := ''; для строки.

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

person Francesca    schedule 03.09.2010
comment
... или если код выполняет низкоуровневые действия, которые мешают компилятору автоматически генерировать очищающий код. - person Mason Wheeler; 04.09.2010
comment
Я попробовал это, и я все еще вижу увеличение использования памяти каждый раз, когда я запускаю. Это единственный признак, по которому я должен проверить это, поскольку варианты не выделяются FastMM и не отображаются в отчете об утечке памяти. Но он значительно снизился, а это значит, что это помогает, и есть еще кое-что. :( - person Mason Wheeler; 04.09.2010