Delphi 使用dll中的接口安全吗

Delphi 使用dll中的接口安全吗,delphi,memory-management,dll,Delphi,Memory Management,Dll,当我想要导出DLL中的类时,从接口派生类并通过导出的函数返回该接口是正确的方法吗 //exported dll function, which is used in the exe. function MyClass_Create: IMyClass; begin result := TMyClass.Create; end; 内存管理呢?我可以传入/传出不同的接口和字符串而无需担心和崩溃吗 IMyClass = interface procedure SetString(aMsg:

当我想要导出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;

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

字符串是不同的。无论您是导出接口还是导出平面函数,都不重要——同样的限制也适用


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

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

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

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


正如字符串会出现问题一样,动态数组也会出现问题。试图跨模块边界pas动态阵列是不安全的。对于宽字符串,没有比它更方便的解决方案。您可以使用变量数组,但与WideString相比,它相当笨重。

在使用接口的循环引用(即引用共享接口的实现类)时,请注意潜在的内存泄漏问题。在这种情况下,Delphi缺少垃圾收集器或“归零弱指针”功能。请参见循环引用是引用计数的常见问题。脏把戏
指针(IntRef):=nil
在不更改refcount的情况下为接口引用空可能会有所帮助。