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

加载DLL时出现‘Duplicates not allowed’错误的原因是什么?

Embarcadero升级后LoadLibrary加载DLL触发EListError异常的解决思路

问题场景

从RAD Studio 10.1升级到11.1后,C++主程序调用LoadLibrary加载目标DLL时失败,抛出异常:

First chance exception at $74F3CA42. Exception class EListError with message 'Duplicates not allowed'.

异常调用栈

:74f3ca42 KERNELBASE.RaiseException + 0x62
:55c2c179 CustomIPTransport280.@System@Generics@Collections@%TDictionary__2$5_GUIDp17System@TMetaClass%@Add$qqrrx5_GUIDxp17System@TMetaClass + 0x4d
:555c923e IndyIPCommon280.@Ippeercommon@initialization$qqrv + 0x5e
:322599e1 ; B:\Build\CC32280MT.DLL
:32259f88 CC32280MT.__wstartupd + 0xc0
:07c96f5a ; System.Win.Stdvcl
:7702dd42 ntdll.RtlActivateActivationContextUnsafeFast + 0xe2
:77031843 ; ntdll.dll
:770319b1 ; ntdll.dll
:77032255 ntdll.RtlIsCriticalSectionLockedByThread + 0xb5
:7702e272 ; ntdll.dll
:7702deb6 ntdll.LdrLoadDll + 0xf6
:74f21bc6 ; C:\WINDOWS\SysWOW64\KERNELBASE.dll
:74f3cca1 KERNELBASE.LoadLibraryW + 0x11
:00481026 TfrmTkTicketInquiry::actEmailExecute(this=:04639B90, Sender=:02B24A60)
:50173bfa rtl280.@System@Classes@TBasicAction@Execute$qqrv + 0x12
:5650799b vcl280.@Vcl@Controls@TControl@Perform$qqruiuii + 0x27
:5650c6ad vcl280.@Vcl@Controls@TWinControl@IsControlMouseMsg$qqrr24Winapi@Messages@TWMMouse + 0xb5
:56595367 ; B:\Build\vcl280.bpl
:5650c3f7 vcl280.@Vcl@Controls@TWinControl@MainWndProc$qqrr24Winapi@Messages@TMessage + 0x2f
:50174a32 rtl280.@System@Classes@TDataModule@WriteHeight$qqrp22System@Classes@TWriter + 0x22
:75070f1b USER32.AddClipboardFormatListener + 0x4b
:75067eca ; C:\WINDOWS\SysWOW64\USER32.dll
:75065c3a ; C:\WINDOWS\SysWOW64\USER32.dll
:75065a00 USER32.DispatchMessageW + 0x10
:5664d69c vcl280.@Vcl@Forms@TApplication@ProcessMessage$qqrr6tagMSG + 0xf8
:75437464 ; C:\WINDOWS\SysWOW64\SHELL32.DLL

已知背景:

  • 主程序和DLL均为C++编写,已在RAD 11.1中重新创建cbproj文件,解决了多数升级问题
  • 两者都集成了DevExpress C++组件
  • 其他EXE可正常加载该DLL,仅当前EXE出现异常

核心原因

从调用栈可见,异常触发在CustomIPTransport280的TDictionary.Add方法,属于Indy组件(IndyIPCommon280)的初始化阶段。本质是主程序与DLL重复注册了同一个GUID对应的元类,导致Indy初始化时向字典添加重复键值对,触发"Duplicates not allowed"错误。

常见诱因:

  • 主程序和DLL对Indy组件的链接方式不一致(一个静态链接、一个动态链接),导致初始化逻辑重复执行
  • DevExpress组件自带的Indy版本与项目中使用的公共Indy版本冲突,引发重复注册
  • 项目包依赖配置错误,重复加载了包含Indy注册逻辑的BPL包

解决步骤

  • 统一Indy组件链接方式:确保主程序和DLL要么都动态链接到同一版本的Indy BPL包,要么都静态链接。检查项目选项的Packages设置,确认Indy相关包(如IndyIPCommon280.bpl、CustomIPTransport280.bpl)版本一致,无重复引用。
  • 排查DevExpress依赖冲突:更新DevExpress到适配RAD 11.1的最新版本,或在DevExpress配置中指定使用项目的Indy组件,避免私有版本冲突。
  • 清理重复初始化代码:检查主程序和DLL的初始化部分,移除手动注册Indy组件的重复代码,确保注册逻辑仅在一方执行(通常由主程序或共享包统一处理)。
  • 对齐项目配置:对比能正常加载DLL的其他EXE的项目配置,重点核对编译器选项(如Runtime Packages、Linking)、依赖包列表及加载顺序,确保输出目录中组件库版本统一。
  • 定位重复注册源:使用Indy调试版本,在Ippeercommon单元的初始化代码处设断点,查看重复添加的GUID和元类,精准定位重复注册的模块。

内容的提问来源于stack exchange,提问作者MathewJoy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:20:16