如何在 Delphi 中正确释放/最终化 ActiveX DLL?

发布于 2024-08-12 18:13:03 字数 1336 浏览 5 评论 0原文

我们在这里使用一个名为 ODNCServer 的类 - 在初始化时,会创建一个 TAutoObjectFactory 对象:

initialization
  pAutoObjectFactory := TAutoObjectFactory.Create(ComServer, TODNCServer, Class_ODNCServer, ciSingleInstance, tmApartment);

现在 FastMM 抱怨内存泄漏,因为该对象没有在任何地方释放。如果我添加这样的终结语句,

finalization
  if assigned(pAutoObjectFactory) then
    TAutoObjectFactory(pAutoObjectFactory).Free;

那么该对象将被释放,但是之后会弹出有关内存泄漏的FastMM对话框,所以实际上,操作系统似乎正在卸载DLL,而不是程序。 ODNCServer 的实例是这样创建

fODNCServer := TODNCServer.Create(nil);
//register into ROT
OleCheck(
 RegisterActiveObject(
   fODNCServer.DefaultInterface,            // instance
   CLASS_ODNCServer,    // class ID
   ACTIVEOBJECT_STRONG,       //strong registration flag
   fODNCServerGlobalHandle //registration handle result
 ));

和释放的:

if ((assigned(fODNCServer)) and (fODNCServerGlobalHandle <> -1)) then
begin
  Reserved := nil;
  OleCheck(RevokeActiveObject(fODNCServerGlobalHandle,Reserved));
  fDTRODNCServerGlobalHandle := -1;
end;
FreeAndNil(fODNCServer);

那么,有人知道我必须更改什么才能消除内存泄漏吗?顺便说一句,我也尝试过使用FastMM的RegisterExpectedMemoryLeaks来注册并忽略泄漏,但这似乎不起作用。此外,即使这只是一种解决方法,我想知道执行此操作的正确方法。

We are using a class called ODNCServer here - at initialization, an TAutoObjectFactory object is created:

initialization
  pAutoObjectFactory := TAutoObjectFactory.Create(ComServer, TODNCServer, Class_ODNCServer, ciSingleInstance, tmApartment);

Now FastMM is complaining about a memory leak because this object isn't freed anywhere. If I add a finalization statement like this

finalization
  if assigned(pAutoObjectFactory) then
    TAutoObjectFactory(pAutoObjectFactory).Free;

then the object is freed, but after the FastMM dialog about the memory leak pops up, so actually, the OS seems to be unloading the DLL, not the program. Instances of ODNCServer are created like this

fODNCServer := TODNCServer.Create(nil);
//register into ROT
OleCheck(
 RegisterActiveObject(
   fODNCServer.DefaultInterface,            // instance
   CLASS_ODNCServer,    // class ID
   ACTIVEOBJECT_STRONG,       //strong registration flag
   fODNCServerGlobalHandle //registration handle result
 ));

and freed like this:

if ((assigned(fODNCServer)) and (fODNCServerGlobalHandle <> -1)) then
begin
  Reserved := nil;
  OleCheck(RevokeActiveObject(fODNCServerGlobalHandle,Reserved));
  fDTRODNCServerGlobalHandle := -1;
end;
FreeAndNil(fODNCServer);

So, does anybody know what I have to change to get rid of that memory leak? By the way, I also tried using FastMM's RegisterExpectedMemoryLeaks to register and ignore the leak, but this doesn't seem to work. Additionally, even if, it would just be a workaround and I'd like to know the right way to do this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

羁拥 2024-08-19 18:13:03

别担心。这并不是严格意义上的“泄露”。是的,您正在创建一个永远不会释放的对象,但关键字是“an”。单一的。

您的应用程序/DLL 不会“泄漏”内存,因为它会创建这些对象的大量实例,从而不断增加其内存使用量。此外,当进程终止时,该单个工厂对象(以及其他类似对象)使用的内存将被清除。

如果您显示了用于调用 RegisterExpectedMemoryLeak() 的代码,则可能可以确定为什么它无法处理您的特定情况。

Don't worry about it. It's not a "leak" in the strict sense. Yes you are creating an object that is never free'd, but the keyword is "an". Singular.

Your application/DLL will not "leak" memory in the sense that it will create numerous instances of these objects,continually increase it's memory use. Furthermore the memory used by that single factory object (and others like it) will be cleaned up when the process terminates anyway.

If you showed the code you are using to call RegisterExpectedMemoryLeak() it might be possible to determine why it is not working your specific case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文