调用DLL函数触发Access Violation异常的排查与解决求助
解决DLL中SHA256哈希函数交替触发Access Violation的问题
兄弟,我看了你的问题,这种交替出现的Access Violation在Delphi的DLL和主程序交互时太常见了,根本原因就是跨模块的内存管理不兼容。先把你的代码贴出来方便分析:
DLL中的函数代码
function PedirContraseña() : string; var clave, claveCodificada : string; begin clave := InputBox('Autenticación', 'Introduzca la clave de acceso', ''); claveCodificada := SHA256Hash(clave); Result := claveCodificada; end; exports PedirContraseña;
主应用调用代码
function PedirContraseña() : string; external 'seguridad.dll'; procedure Tmenubodega.BitBtn1Click(Sender: TObject); var s : string; begin inherited; s := PedirContraseña; ShowMessage(s); end;
问题根源
Delphi里的string是引用计数的动态字符串,它的内存分配和释放完全依赖当前模块的内存管理器。如果你的DLL和主程序没有使用共享的内存管理器,DLL中分配的字符串内存,主程序在释放时会用自己的内存管理器去操作不属于它的内存块,直接触发Access Violation。而前两次正常、后面交替异常的情况,是因为内存错误的触发有随机性,前两次内存还没被错误覆盖,第三次开始引用计数的矛盾就显现出来了。
解决方案
最稳妥的两种解决方式:
方案1:使用共享内存管理器(最简单)
在DLL和主程序的uses列表最开头加入ShareMem单元——它会让两个模块共用同一个内存管理器,字符串的分配和释放就能跨模块正常工作。
- DLL代码修改:
library seguridad; uses ShareMem, // 必须放在第一个位置 SysUtils, Forms, Dialogs, 你的SHA256相关单元; // 你的PedirContraseña函数代码...
- 主程序代码修改:
program 你的主程序名; uses ShareMem, // 同样放在第一个位置 Vcl.Forms, 你的主窗体单元; // 主程序剩余代码...
方案2:改用PChar手动管理内存(适合不能用ShareMem的场景)
如果因为某些限制不能用共享内存管理器,那可以改用PChar传递字符串,手动控制内存分配:
- DLL函数修改:
function PedirContraseña(out Buffer: PChar; BufferSize: Integer): Integer; stdcall; var clave, claveCodificada: string; begin clave := InputBox('Autenticación', 'Introduzca la clave de acceso', ''); claveCodificada := SHA256Hash(clave); Result := Length(claveCodificada); if BufferSize >= Result + 1 then // 要留位置存字符串结束符 StrPCopy(Buffer, claveCodificada); end; exports PedirContraseña;
- 主程序调用代码修改:
function PedirContraseña(out Buffer: PChar; BufferSize: Integer): Integer; stdcall; external 'seguridad.dll'; procedure Tmenubodega.BitBtn1Click(Sender: TObject); var s: string; buf: array[0..63] of Char; // SHA256哈希固定是64字符,数组大小足够 len: Integer; begin inherited; len := PedirContraseña(buf, SizeOf(buf)); SetString(s, buf, len); ShowMessage(s); end;
注意事项
- 方案1中
ShareMem必须放在uses的第一个位置,这样它才能优先初始化共享内存管理器。 - 如果你的SHA256哈希函数内部也有内存分配逻辑,要确保它的内存管理和当前模块一致,不过大部分第三方哈希库都会处理好这个问题。
内容的提问来源于stack exchange,提问作者davidrgh
相关产品推荐
相关产品推荐

