Delphi12/13 DLL中TApdWinsockPort组件初始化异常求助
在Delphi 12/13中开发带TApdWinsockPort组件的DLL时的初始化异常问题及解决方法
问题详情
- 开发场景:Delphi 12/13环境下开发DLL,窗体中使用
TApdWinsockPort组件 - 异常触发:宿主EXE调用DLL的Initialize过程,执行
Application.CreateForm时 - 错误表现:在
EnumHostAddresses函数中触发访问违例,报错行:
异常信息:if SockFuncs.GetHostName (@HostStr, SizeOf (HostStr)) = 0 then beginFirst chance exception at $00000000. Exception class $C0000005 with message 'access violation at 0x00000000: access of address 0x00000000' - 调试结论:
SockFuncs未初始化,所有函数指针均为nil
原因分析
查看AsyncPro的AwWnsock单元源码,发现初始化逻辑存在DLL环境兼容问题:
if not IsLibrary then //SZ: bugfix Loader Lock Problem!! (never ever call LoadLibrary from initialization / dllmain)
ApdSocket := TApdDeviceSocket.Create(nil);
DLL环境下IsLibrary返回True,导致负责初始化Winsock函数指针的TApdDeviceSocket未被创建,最终触发访问违例。
可行解决方法
方法1:手动初始化Winsock组件
在DLL的Initialize过程中,调用Application.CreateForm之前,主动创建TApdDeviceSocket实例,确保Winsock函数指针完成初始化:
procedure Initialize; var TempSocket: TApdDeviceSocket; begin // 主动创建TApdDeviceSocket,触发Winsock函数指针初始化 TempSocket := TApdDeviceSocket.Create(nil); // 无需手动释放,AsyncPro内部会管理该实例的生命周期 Application.CreateForm(TYourDllForm, YourDllForm); end;
方法2:修改AsyncPro源码兼容DLL环境
调整AwWnsock单元的初始化逻辑,将TApdDeviceSocket的创建延迟到首次使用Winsock功能时。例如在EnumHostAddresses函数开头增加检查:
function EnumHostAddresses(List: TStrings): Boolean; begin // 检查并初始化TApdDeviceSocket if not Assigned(ApdSocket) then ApdSocket := TApdDeviceSocket.Create(nil); // 原有函数逻辑... end;
此方法需要修改AsyncPro源码,适合有源码修改权限的场景。
补充说明
该问题并非个例,已有其他开发者在TurboPack AsyncPro的相关Issue中反馈过类似情况,相关测试案例的讨论可参考对应Issue内容。
内容的提问来源于stack exchange,提问作者Dennis van Vugt
相关产品推荐
相关产品推荐

