Delphi的Sharemem - 当它不需要时

10

我知道当我在Delphi应用程序和Delphi动态链接库之间共享字符串时,需要将Sharemem添加到应用程序和dll项目源代码的uses子句中。

但是,如果dll导出仅接受Pchars的函数,但在某些dll方法内部我使用了strings,那么我是否也需要使用sharemem?让我展示一段示例代码:

procedure ShowMyCustomMessage(aMessage : Pchar);
var
  vUselessString : string;
begin
  vUselessString := aMessage;
  ShowMessage(vUselessString);
end;

exports
  ShowMyCustomMessage;

在这种简单且无用的情况下,dll接受一个Pchar,但在导出方法内部,dll创建了一个字符串变量。我应该也添加ShareMem吗?
那WideString呢?传递WideString参数需要使用ShareMem吗?

2
据我所知,如果您想使用已弃用的borlndmm.dll内存管理器,则应使用ShareMem。但自Delphi 2007以来,这不是一个好主意。您最好使用基于FastMM4的SimpleShareMem,它速度更快 - Arnaud Bouchez
@Arnaud,你确定borlndmm已经被弃用了吗?我没有看到任何人谈论它。 - Rafael Colucci
@RafaelColucci:旧版 borlndmm.dll。令人困惑的是,所有内存管理器DLL都有这个名称。当前版本的Delphi / C++ Builder使用FastMM编译为'borlndmm.dll',已经使用了几年时间。 - David
2
以我个人看法,使用外部库是一种已经过时的技术,只有在某个库无法重新编译使用 FastMM4 的情况下才应该使用。事实上,FastMM4 拥有内置的共享系统(基于每个进程映射文件),避免了使用外部的 borlndmm.dll 文件,这个文件仅用于向后兼容第三方库,而这些库却没有源代码。 - Arnaud Bouchez
这是一个旧的帖子,但我想补充一下,使用ShareMem提供了不重新编译即可切换内存管理器的绝妙能力。例如,我有一个经过优化的FastMM、一个“fulldebug”FastMM,以及杀手级别的SafeMM。由于我们的服务器是多线程的,这也使我们能够在性能调优时轻松地对内存管理器进行基准测试。 - Jon Robertson
1个回答

18
如果在一个模块(如DLL/EXE)中分配内存并在另一个模块中释放内存,那么您需要使用Sharemem。当您在模块之间传递字符串时,通常会发生这种情况。
在您给出的示例中,没有必要使用Sharemem。调用者分配PChar的内存,并且调用者不会释放它。被调用者中的字符串是在被调用者中分配和释放的。
下面是一个需要使用Sharemem的示例:
function GetString: string;
begin
  Result := 'hello';
end;

此处字符串的内存是在调用者中分配的,但将由调用方释放。

WideString的情况非常特殊。 WideString是COM BSTR类型的包装器。它使用共享的COM分配器进行分配和释放。因此,它不使用Delphi分配器,您可以安全地在模块之间传递WideString而无需使用Sharemem。


很好知道,但如果DLL接受的是WideString而不是PChar呢? - Rafael Colucci
我知道,那只是额外的加分。谢谢你的一切。 - Rafael Colucci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接