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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 10:25:09