如何阻止这种变体内存泄漏?
我使用的是旧的脚本引擎,其创建者不再支持该引擎,并且遇到内存泄漏问题。它使用 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;
编辑:回应 Rob Kennedy 在评论中的问题:
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 函数中的变体来实现的。 (在这种情况下,更改函数的返回类型将不起作用。)
I'm using an old script engine that's no longer supported by its creators, and having some trouble with memory leaks. It uses a function written in ASM to call from scripts into Delphi functions, and returns the result as an integer then passes that integer as an untyped parameter to another procedure that translates it into the correct type.
This works fine for most things, but when the return type of the Delphi function was Variant, it leaks memory because the variant is never getting disposed of. Does anyone know how I can take an untyped parameter containing a variant and ensure that it will be disposed of properly? This will probably involve some inline assembly.
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;
EDIT: Responding to Rob Kennedy's question in comments:
AnsiString conversion works like this:
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;
That works fine and doesn't produce memory leaks. When I try to do the same thing with a variant as the input parameter, and assign the original Null
on the second procedure, the memory leaks still happen.
The variants mostly contain strings--the script in question is used to generate XML--and they got there by assigning a Delphi string to a variant in the Delphi function that this script is calling. (Changing the return type of the function wouldn't work in this case.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您是否尝试过与字符串相同的技巧,除了使用 Variant 时,您应该使用
UnAssigned
而不是Null
来释放它,就像您所做的s 一样: = '';
为字符串。顺便说一句,我能想到的唯一需要显式释放字符串、变体等的原因之一是在使用某些
ThreadVar
时。Have you tried the same trick as with the string, except that with a Variant, you should put
UnAssigned
instead ofNull
to free it, like you dids := '';
for the string.And by the way, one of the only reasons I can think of that requires to explicitly free the strings, Variants, etc... is when using some
ThreadVar
.