You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DLL与WideString并行调用时的竞态条件问题排查

解决Delphi多线程调用DLL时的EAggregateException异常

这是一个典型的Delphi DLL多线程调用场景下,字符串类型兼容性与内存管理冲突导致的问题。让我帮你拆解原因并给出可行的解决方案:

问题根源

你遇到的异常核心原因在于DLL中使用了Delphi特有的String(UnicodeString)类型进行字符串转换,而该类型完全依赖Delphi的私有内存管理器。具体来说:

  • 当你执行String(ASource).ToUpper时,首先会把WideString(标准COM BSTR类型)转换为Delphi私有的UnicodeString,这一步会在DLL的内存堆上分配内存;
  • ToUpper方法会生成一个新的UnicodeString,再次占用DLL堆内存;
  • 最后赋值给AResult(WideString)时,又会把UnicodeString转换回BSTR,这一步虽然使用了COM的系统内存分配(SysAllocString),但前面的Delphi字符串操作已经引入了风险。

在多线程并行调用时,Delphi的内存管理器虽然声称线程安全,但在跨模块(EXE调用DLL)的场景下,容易出现线程同步冲突或者堆操作异常——尤其是当你没有共享内存管理器时(这一点你做的是对的,因为要支持多语言调用)。而当你直接赋值AResult := ASource时,只是传递了BSTR的指针,没有涉及Delphi私有内存的分配/释放,因此不会触发异常。

解决方案

既然你的目标是让DLL支持多编程语言调用,必须坚持使用跨语言兼容的标准类型(比如WideString/BSTR),避免使用Delphi特有的类型。以下是两种可行的修改方案:

方案1:直接操作WideString,使用标准API或Delphi的WideString兼容函数

修改DLL中的MyUpper函数,直接对WideString进行大写转换,完全避开Delphi私有字符串类型:

library MyDLL;
uses System.SysUtils;

procedure MyUpper(const ASource: WideString; out AResult: WideString); stdcall;
begin
  // 使用Delphi的WideUpperCase函数,直接操作WideString(BSTR)
  AResult := WideUpperCase(ASource);
end;

exports MyUpper;
end.

或者使用Win32原生API CharUpperW,兼容性更强:

library MyDLL;
uses System.SysUtils, Windows;

procedure MyUpper(const ASource: WideString; out AResult: WideString); stdcall;
var
  LBuffer: PWideChar;
begin
  GetMem(LBuffer, Length(ASource) * SizeOf(WideChar) + SizeOf(WideChar));
  try
    CharUpperW(LBuffer, PWideChar(ASource));
    AResult := LBuffer;
  finally
    FreeMem(LBuffer);
  end;
end;

exports MyUpper;
end.

方案2:如果必须使用Delphi字符串类型(不推荐,不利于多语言兼容)

如果你因为某些原因必须使用Delphi的String类型,需要确保DLL和所有调用端共享同一个内存管理器。但这会破坏多语言调用的目标,所以仅作为备选:

  1. 在DLL和EXE中都添加ShareMem单元到uses列表的最顶部;
  2. 确保DLL和EXE使用相同版本的Delphi编译,并且链接相同的运行时库。

关键注意事项

  • 导出DLL函数时,始终使用跨语言兼容的类型:WideString、PChar、Integer、BOOL(避免用Delphi原生Boolean,它是1字节,跨语言易出问题)等;
  • 避免在DLL的导出函数中使用Delphi特有的类型(如String、TObject子类等),这些类型无法被其他语言正确识别;
  • 多线程调用DLL时,确保所有涉及内存分配的操作都使用线程安全的标准API或跨模块兼容的内存管理方式。

最后,修改后的DLL应该能在多线程并行调用下稳定运行,同时保持对多编程语言的兼容性。

内容的提问来源于stack exchange,提问作者Z.B.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:29:00