Excel与Delphi 12间字符串传递问题:调用DLL时Excel崩溃重启
问题分析与解决方法
核心问题
Excel崩溃的根源是Delphi的PChar与VBAString在字符串输出参数上的类型兼容和内存管理不匹配,64位环境下的指针宽度差异进一步放大了这个问题。
代码问题拆解
Delphi端代码问题
你的DLL中输出参数XXstr声明为var XXstr:PChar,但VBA传递的ByRef String对应COM标准的BSTR类型,两者直接交互会触发内存访问违规:
- 64位下Delphi的
PChar默认是PWideChar,但var PChar传递的是指针的指针,和VBA期望的BSTR指针类型不匹配。 - 字符串输出的内存逻辑缺失:如果DLL内部分配内存,VBA无法正确释放;如果依赖VBA提前分配缓冲区,又没有指定大小,会导致缓冲区溢出。
VBA端代码问题
ByRef XXstr As String的声明无法直接匹配Delphi的var PChar参数,64位环境下的指针类型不兼容直接导致Excel内存访问出错。
修正方案
1. 修改Delphi DLL的参数声明
将字符串参数统一适配COM的BSTR类型(对应VBAString),利用自动内存管理机制避免崩溃:
procedure P_GERGDLL(T, rho: Double; NID: Integer; KIDstr, Xstr: PWideChar; var Z, P, dP_dT, dP_drho, dP_dV, dV_dT, drho_dT: Double; var XXstr: WideString; var ier: Integer); stdcall;
- 输入参数
KIDstr、Xstr用PWideChar直接接收VBA传递的BSTR指针。 - 输出参数
XXstr改用var WideString,Delphi会自动处理BSTR的内存分配,VBA可直接接收。
2. 修改VBA的声明与调用
保持输入参数为ByVal String,输出参数XXstr沿用ByRef String,确保类型完全匹配:
Declare PtrSafe Sub P_GERGDLL Lib "C:\Users\louis chapoy\test DLL\Win64\Debug\ThermophiDLL.dll" _ (ByVal T As Double, ByVal rho As Double, ByVal NID As Integer, ByVal KSTR As String, _ ByVal Xstr As String, ByRef Z As Double, ByRef P As Double, ByRef dpdt As Double, _ ByRef dpdr As Double, ByRef dpdv As Double, ByRef dvdt As Double, ByRef drdt As Double, _ ByRef XXstr As String, ByRef ier As Integer) ' 调用前无需提前分配XXstr长度,Delphi会自动完成内存分配 P_GERGDLL T, rho, NZ, KIDstr, Xstr, Z, PP, dpdt, dpdr, dpdv, dvdt, drdt, XXstr, ier
3. 关键注意事项
- 务必保留Delphi项目
uses子句顶部的ShareMem,它负责协调Delphi与VBA之间的共享内存分配。 - 64位环境下,所有字符串相关参数必须严格匹配:Delphi的
PWideChar对应VBA的ByVal String,WideString对应ByRef String。 - 禁止在DLL中手动分配
PChar内存后返回给VBA,否则会导致内存泄漏或二次崩溃。
内容的提问来源于stack exchange,提问作者Louis Chapoy
相关产品推荐
相关产品推荐

