【问题标题】:Is it safe to use interfaces from dll使用dll中的接口是否安全
【发布时间】:2012-01-13 05:55:44
【问题描述】:

当我想在 DLL 中导出一个类时,从接口派生它并通过导出函数返回该接口是否正确?

//exported dll function, which is used in the exe.
function MyClass_Create: IMyClass;
begin
  result := TMyClass.Create;
end;

内存管理呢?我可以传入/传出不同的接口和字符串而不用担心和崩溃吗?

IMyClass = interface
  procedure SetString(aMsg: string);
  function GetString: string;

  procedure SetClass(aClass: ITestClass);
  function GetClass: ITestClass;
end;

【问题讨论】:

    标签: delphi memory-management dll


    【解决方案1】:

    接口引用与内存管理正交。通常你导出一个从dll返回接口引用的函数,并不关心内存管理。使用引用计数接口,您可以确保实现接口的对象实例也将在 dll 中被释放。

    字符串不同。无论您是导出接口还是导出平面函数都没有关系——同样的限制适用。

    顺便说一句,您的问题标题不正确,Delphi 中没有“接口实例”。

    【讨论】:

    • 在使用接口的循环引用(即引用共享接口的实现类)时注意潜在的内存泄漏问题 - 在这种情况下,Delphi 缺少垃圾收集器或“归零”弱指针”功能。见blog.synopse.info/post/2011/12/08/…
    • 循环引用是引用计数的常见问题。肮脏的技巧Pointer(IntRef):= nil 在不更改引用计数的情况下将接口引用设为空会有所帮助。
    【解决方案2】:

    使用这样的接口将确保实现该接口的对象将在同一个堆上创建和释放。

    但是,这并不能解决动态字符串类型在不同堆上分配和释放的问题。有很多可能的解决方案,但在我看来,最好的方法是跨模块边界使用 WideString。

    WideString 类型是 COM BSTR 的包装器,并在共享 COM 堆上分配。您只需要使用 WideString 作为接口。实现类的内部可以使用原生 Delphi 字符串。

    正如字符串存在问题一样,动态数组也是如此。尝试跨模块边界传递动态数组是不安全的。没有与 WideString 类似的方便的解决方案。您可以使用变体数组,但与 WideString 相比,这非常笨拙。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 2020-05-10
      • 1970-01-01
      • 2014-01-05
      • 1970-01-01
      • 2022-06-25
      • 1970-01-01
      相关资源
      最近更新 更多